mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Separate buffering per entry type in WebPerformance (#36737)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/36737 ## Changelog: [Internal] - Use `BoundedConsumableBuffer` in WebPerformance This makes use of the `BoundedConsumableBuffer` container type, introduced in D44544057, for buffering/observing arbitrary performance entry types in `WebPerformance/PerformanceEntryReporter`, thus generalizing what was earlier done in an ad-hoc way for marks and measures, and also allowing to have both observable/retrievable/buffered property for arbitrary performance entry type (with the ultimate goal of adding custom entry types, related to e.g. startup timing, something that we currently have an ad hoc API for). Reviewed By: sammy-SC Differential Revision: D44574241 fbshipit-source-id: a858712ff1cf468914a80c99f6b82d060cb0b702
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1387179b89
commit
950472018d
@@ -12,71 +12,66 @@
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
// All the unflushed entries beyond this amount will get discarded, with
|
||||
// the amount of discarded ones sent back to the observers' callbacks as
|
||||
// "droppedEntryCount" value
|
||||
static constexpr size_t MAX_ENTRY_BUFFER_SIZE = 1024;
|
||||
|
||||
namespace facebook::react {
|
||||
EventTag PerformanceEntryReporter::sCurrentEventTag_{0};
|
||||
|
||||
RawPerformanceEntry PerformanceMark::toRawPerformanceEntry() const {
|
||||
return {
|
||||
name,
|
||||
static_cast<int>(PerformanceEntryType::MARK),
|
||||
timeStamp,
|
||||
0.0,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt};
|
||||
}
|
||||
|
||||
RawPerformanceEntry PerformanceMeasure::toRawPerformanceEntry() const {
|
||||
return {
|
||||
name,
|
||||
static_cast<int>(PerformanceEntryType::MEASURE),
|
||||
timeStamp,
|
||||
duration,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt};
|
||||
}
|
||||
|
||||
PerformanceEntryReporter &PerformanceEntryReporter::getInstance() {
|
||||
static PerformanceEntryReporter instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
PerformanceEntryReporter::PerformanceEntryReporter() {
|
||||
// For mark entry types we also want to keep the lookup by name, to make
|
||||
// sure that marks can be referenced by measures
|
||||
getBuffer(PerformanceEntryType::MARK).hasNameLookup = true;
|
||||
}
|
||||
void PerformanceEntryReporter::setReportingCallback(
|
||||
std::optional<AsyncCallback<>> callback) {
|
||||
callback_ = callback;
|
||||
}
|
||||
|
||||
void PerformanceEntryReporter::startReporting(PerformanceEntryType entryType) {
|
||||
int entryTypeIdx = static_cast<int>(entryType);
|
||||
reportingType_[entryTypeIdx] = true;
|
||||
durationThreshold_[entryTypeIdx] = DEFAULT_DURATION_THRESHOLD;
|
||||
auto &buffer = getBuffer(entryType);
|
||||
buffer.isReporting = true;
|
||||
buffer.durationThreshold = DEFAULT_DURATION_THRESHOLD;
|
||||
}
|
||||
|
||||
void PerformanceEntryReporter::setDurationThreshold(
|
||||
PerformanceEntryType entryType,
|
||||
double durationThreshold) {
|
||||
durationThreshold_[static_cast<int>(entryType)] = durationThreshold;
|
||||
getBuffer(entryType).durationThreshold = durationThreshold;
|
||||
}
|
||||
|
||||
void PerformanceEntryReporter::stopReporting(PerformanceEntryType entryType) {
|
||||
reportingType_[static_cast<int>(entryType)] = false;
|
||||
getBuffer(entryType).isReporting = false;
|
||||
}
|
||||
|
||||
void PerformanceEntryReporter::stopReporting() {
|
||||
reportingType_.fill(false);
|
||||
for (auto &buffer : buffers_) {
|
||||
buffer.isReporting = false;
|
||||
}
|
||||
}
|
||||
|
||||
GetPendingEntriesResult PerformanceEntryReporter::popPendingEntries() {
|
||||
std::lock_guard<std::mutex> lock(entriesMutex_);
|
||||
GetPendingEntriesResult res = {
|
||||
std::vector<RawPerformanceEntry>(), droppedEntryCount_};
|
||||
for (auto &buffer : buffers_) {
|
||||
buffer.entries.consume(res.entries);
|
||||
}
|
||||
|
||||
// Sort by starting time (or ending time, if starting times are equal)
|
||||
std::sort(
|
||||
res.entries.begin(),
|
||||
res.entries.end(),
|
||||
[](const RawPerformanceEntry &lhs, const RawPerformanceEntry &rhs) {
|
||||
if (lhs.startTime != rhs.startTime) {
|
||||
return lhs.startTime < rhs.startTime;
|
||||
} else {
|
||||
return lhs.duration < rhs.duration;
|
||||
}
|
||||
});
|
||||
|
||||
GetPendingEntriesResult res = {std::move(entries_), droppedEntryCount_};
|
||||
entries_ = {};
|
||||
droppedEntryCount_ = 0;
|
||||
return res;
|
||||
}
|
||||
@@ -91,24 +86,39 @@ void PerformanceEntryReporter::logEntry(const RawPerformanceEntry &entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.duration < durationThreshold_[entry.entryType]) {
|
||||
// The entries duration is lower than the desired reporting threshold, skip
|
||||
// return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(entriesMutex_);
|
||||
|
||||
if (entries_.size() == MAX_ENTRY_BUFFER_SIZE) {
|
||||
auto &buffer = buffers_[entry.entryType];
|
||||
|
||||
if (entry.duration < buffer.durationThreshold) {
|
||||
// The entries duration is lower than the desired reporting threshold, skip
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer.hasNameLookup) {
|
||||
auto overwriteCandidate = buffer.entries.getNextOverwriteCandidate();
|
||||
if (overwriteCandidate != nullptr) {
|
||||
auto it = buffer.nameLookup.find(overwriteCandidate);
|
||||
if (it != buffer.nameLookup.end() && *it == overwriteCandidate) {
|
||||
buffer.nameLookup.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto pushResult = buffer.entries.add(std::move(entry));
|
||||
if (pushResult ==
|
||||
BoundedConsumableBuffer<RawPerformanceEntry>::PushStatus::DROP) {
|
||||
// Start dropping entries once reached maximum buffer size.
|
||||
// The number of dropped entries will be reported back to the corresponding
|
||||
// PerformanceObserver callback.
|
||||
droppedEntryCount_ += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
entries_.emplace_back(entry);
|
||||
if (buffer.hasNameLookup) {
|
||||
buffer.nameLookup.insert(&buffer.entries.back());
|
||||
}
|
||||
|
||||
if (entries_.size() == 1) {
|
||||
if (buffer.entries.getNumToConsume() == 1) {
|
||||
// If the buffer was empty, it signals that JS side just has possibly
|
||||
// consumed it and is ready to get more
|
||||
scheduleFlushBuffer();
|
||||
@@ -119,95 +129,75 @@ void PerformanceEntryReporter::mark(
|
||||
const std::string &name,
|
||||
double startTime,
|
||||
double duration) {
|
||||
// Register the mark for further possible "measure" lookup, as well as add
|
||||
// it to a circular buffer:
|
||||
PerformanceMark &mark = marksBuffer_[marksBufferPosition_];
|
||||
marksBufferPosition_ = (marksBufferPosition_ + 1) % marksBuffer_.size();
|
||||
marksCount_ = std::min(marksBuffer_.size(), marksCount_ + 1);
|
||||
|
||||
if (!mark.name.empty()) {
|
||||
// Drop off the oldest mark out of the queue, but only if that's indeed the
|
||||
// oldest one
|
||||
auto it = marksRegistry_.find(&mark);
|
||||
if (it != marksRegistry_.end() && *it == &mark) {
|
||||
marksRegistry_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
mark.name = name;
|
||||
mark.timeStamp = startTime;
|
||||
marksRegistry_.insert(&mark);
|
||||
|
||||
logEntry(
|
||||
{name,
|
||||
static_cast<int>(PerformanceEntryType::MARK),
|
||||
startTime,
|
||||
duration,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt});
|
||||
logEntry(RawPerformanceEntry{
|
||||
name,
|
||||
static_cast<int>(PerformanceEntryType::MARK),
|
||||
startTime,
|
||||
duration,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt});
|
||||
}
|
||||
|
||||
void PerformanceEntryReporter::clearEntries(
|
||||
PerformanceEntryType entryType,
|
||||
const char *entryName) {
|
||||
if (entryType == PerformanceEntryType::MARK ||
|
||||
entryType == PerformanceEntryType::UNDEFINED) {
|
||||
if (entryType == PerformanceEntryType::UNDEFINED) {
|
||||
// Clear all entry types
|
||||
for (int i = 1; i < NUM_PERFORMANCE_ENTRY_TYPES; i++) {
|
||||
clearEntries(static_cast<PerformanceEntryType>(i), entryName);
|
||||
}
|
||||
} else {
|
||||
auto &buffer = getBuffer(entryType);
|
||||
if (entryName != nullptr) {
|
||||
// remove a named mark from the mark/measure registry
|
||||
PerformanceMark mark{{entryName, 0}};
|
||||
marksRegistry_.erase(&mark);
|
||||
|
||||
clearCircularBuffer(
|
||||
marksBuffer_, marksCount_, marksBufferPosition_, entryName);
|
||||
if (buffer.hasNameLookup) {
|
||||
RawPerformanceEntry entry{
|
||||
entryName,
|
||||
static_cast<int>(entryType),
|
||||
0.0,
|
||||
0.0,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt};
|
||||
buffer.nameLookup.erase(&entry);
|
||||
}
|
||||
buffer.entries.clear([entryName](const RawPerformanceEntry &entry) {
|
||||
return std::strcmp(entry.name.c_str(), entryName) == 0;
|
||||
});
|
||||
} else {
|
||||
marksCount_ = 0;
|
||||
marksRegistry_.clear();
|
||||
buffer.entries.clear();
|
||||
buffer.nameLookup.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entryType == PerformanceEntryType::MEASURE ||
|
||||
entryType == PerformanceEntryType::UNDEFINED) {
|
||||
if (entryName != nullptr) {
|
||||
clearCircularBuffer(
|
||||
measuresBuffer_, measuresCount_, measuresBufferPosition_, entryName);
|
||||
void PerformanceEntryReporter::getEntries(
|
||||
PerformanceEntryType entryType,
|
||||
const char *entryName,
|
||||
std::vector<RawPerformanceEntry> &res) const {
|
||||
if (entryType == PerformanceEntryType::UNDEFINED) {
|
||||
// Collect all entry types
|
||||
for (int i = 1; i < NUM_PERFORMANCE_ENTRY_TYPES; i++) {
|
||||
getEntries(static_cast<PerformanceEntryType>(i), entryName, res);
|
||||
}
|
||||
} else {
|
||||
const auto &entries = getBuffer(entryType).entries;
|
||||
if (entryName == nullptr) {
|
||||
entries.getEntries(res);
|
||||
} else {
|
||||
measuresCount_ = 0;
|
||||
entries.getEntries(res, [entryName](const RawPerformanceEntry &entry) {
|
||||
return std::strcmp(entry.name.c_str(), entryName) == 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
int lastPos = entries_.size() - 1;
|
||||
int pos = lastPos;
|
||||
while (pos >= 0) {
|
||||
const RawPerformanceEntry &entry = entries_[pos];
|
||||
if (entry.entryType == static_cast<int32_t>(entryType) &&
|
||||
(entryName == nullptr || entry.name == entryName)) {
|
||||
entries_[pos] = entries_[lastPos];
|
||||
lastPos--;
|
||||
}
|
||||
pos--;
|
||||
}
|
||||
entries_.resize(lastPos + 1);
|
||||
}
|
||||
|
||||
std::vector<RawPerformanceEntry> PerformanceEntryReporter::getEntries(
|
||||
PerformanceEntryType entryType,
|
||||
const char *entryName) const {
|
||||
if (entryType == PerformanceEntryType::MARK) {
|
||||
return getCircularBufferContents(
|
||||
marksBuffer_, marksCount_, marksBufferPosition_, entryName);
|
||||
} else if (entryType == PerformanceEntryType::MEASURE) {
|
||||
return getCircularBufferContents(
|
||||
measuresBuffer_, measuresCount_, measuresBufferPosition_, entryName);
|
||||
} else if (entryType == PerformanceEntryType::UNDEFINED) {
|
||||
auto marks = getCircularBufferContents(
|
||||
marksBuffer_, marksCount_, marksBufferPosition_, entryName);
|
||||
auto measures = getCircularBufferContents(
|
||||
measuresBuffer_, measuresCount_, measuresBufferPosition_, entryName);
|
||||
marks.insert(marks.end(), measures.begin(), measures.end());
|
||||
return marks;
|
||||
}
|
||||
return {};
|
||||
std::vector<RawPerformanceEntry> res;
|
||||
getEntries(entryType, entryName, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
void PerformanceEntryReporter::measure(
|
||||
@@ -220,13 +210,6 @@ void PerformanceEntryReporter::measure(
|
||||
double startTimeVal = startMark ? getMarkTime(*startMark) : startTime;
|
||||
double endTimeVal = endMark ? getMarkTime(*endMark) : endTime;
|
||||
double durationVal = duration ? *duration : endTimeVal - startTimeVal;
|
||||
|
||||
measuresBuffer_[measuresBufferPosition_] =
|
||||
PerformanceMeasure{name, startTime, endTime};
|
||||
measuresBufferPosition_ =
|
||||
(measuresBufferPosition_ + 1) % measuresBuffer_.size();
|
||||
measuresCount_ = std::min(measuresBuffer_.size(), measuresCount_ + 1);
|
||||
|
||||
logEntry(
|
||||
{name,
|
||||
static_cast<int>(PerformanceEntryType::MEASURE),
|
||||
@@ -239,10 +222,19 @@ void PerformanceEntryReporter::measure(
|
||||
|
||||
double PerformanceEntryReporter::getMarkTime(
|
||||
const std::string &markName) const {
|
||||
PerformanceMark mark{{std::move(markName), 0}};
|
||||
auto it = marksRegistry_.find(&mark);
|
||||
if (it != marksRegistry_.end()) {
|
||||
return (*it)->timeStamp;
|
||||
RawPerformanceEntry mark{
|
||||
markName,
|
||||
static_cast<int>(PerformanceEntryType::MARK),
|
||||
0.0,
|
||||
0.0,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt};
|
||||
|
||||
const auto &marksBuffer = getBuffer(PerformanceEntryType::MARK);
|
||||
auto it = marksBuffer.nameLookup.find(&mark);
|
||||
if (it != marksBuffer.nameLookup.end()) {
|
||||
return (*it)->startTime;
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@@ -15,50 +15,45 @@
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include "BoundedConsumableBuffer.h"
|
||||
#include "NativePerformanceObserver.h"
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
struct PerformanceMark {
|
||||
std::string name;
|
||||
double timeStamp;
|
||||
|
||||
RawPerformanceEntry toRawPerformanceEntry() const;
|
||||
};
|
||||
|
||||
struct PerformanceMarkHash {
|
||||
size_t operator()(const PerformanceMark *mark) const {
|
||||
return std::hash<std::string>()(mark->name);
|
||||
struct PerformanceEntryHash {
|
||||
size_t operator()(const RawPerformanceEntry *entry) const {
|
||||
return std::hash<std::string>()(entry->name);
|
||||
}
|
||||
};
|
||||
|
||||
struct PerformanceMarkEqual {
|
||||
bool operator()(const PerformanceMark *lhs, const PerformanceMark *rhs)
|
||||
const {
|
||||
struct PerformanceEntryEqual {
|
||||
bool operator()(
|
||||
const RawPerformanceEntry *lhs,
|
||||
const RawPerformanceEntry *rhs) const {
|
||||
return lhs->name == rhs->name;
|
||||
}
|
||||
};
|
||||
|
||||
struct PerformanceMeasure {
|
||||
std::string name;
|
||||
double timeStamp;
|
||||
double duration;
|
||||
|
||||
RawPerformanceEntry toRawPerformanceEntry() const;
|
||||
};
|
||||
|
||||
using PerformanceMarkRegistryType = std::
|
||||
unordered_set<PerformanceMark *, PerformanceMarkHash, PerformanceMarkEqual>;
|
||||
|
||||
// Only the MARKS_BUFFER_SIZE amount of the latest marks will be kept in
|
||||
// memory for the sake of the "Performance.measure" mark name lookup
|
||||
constexpr size_t MARKS_BUFFER_SIZE = 1024;
|
||||
|
||||
// Limit buffer size for the measures kept in memory (only keep the latest ones)
|
||||
constexpr size_t MEASURES_BUFFER_SIZE = 1024;
|
||||
using PerformanceEntryRegistryType = std::unordered_set<
|
||||
const RawPerformanceEntry *,
|
||||
PerformanceEntryHash,
|
||||
PerformanceEntryEqual>;
|
||||
|
||||
// Default duration threshold for reporting performance entries (0 means "report
|
||||
// all")
|
||||
constexpr double DEFAULT_DURATION_THRESHOLD = 0.0;
|
||||
|
||||
// Default buffer size limit, per entry type
|
||||
constexpr size_t DEFAULT_MAX_BUFFER_SIZE = 1024;
|
||||
|
||||
struct PerformanceEntryBuffer {
|
||||
BoundedConsumableBuffer<RawPerformanceEntry> entries{DEFAULT_MAX_BUFFER_SIZE};
|
||||
bool isReporting{false};
|
||||
double durationThreshold{DEFAULT_DURATION_THRESHOLD};
|
||||
bool hasNameLookup{false};
|
||||
PerformanceEntryRegistryType nameLookup;
|
||||
};
|
||||
|
||||
enum class PerformanceEntryType {
|
||||
UNDEFINED = 0,
|
||||
MARK = 1,
|
||||
@@ -67,6 +62,9 @@ enum class PerformanceEntryType {
|
||||
_COUNT = 4,
|
||||
};
|
||||
|
||||
constexpr size_t NUM_PERFORMANCE_ENTRY_TYPES =
|
||||
(size_t)PerformanceEntryType::_COUNT;
|
||||
|
||||
class PerformanceEntryReporter : public EventLogger {
|
||||
public:
|
||||
PerformanceEntryReporter(PerformanceEntryReporter const &) = delete;
|
||||
@@ -87,10 +85,20 @@ class PerformanceEntryReporter : public EventLogger {
|
||||
double durationThreshold);
|
||||
|
||||
GetPendingEntriesResult popPendingEntries();
|
||||
|
||||
void logEntry(const RawPerformanceEntry &entry);
|
||||
|
||||
PerformanceEntryBuffer &getBuffer(PerformanceEntryType entryType) {
|
||||
return buffers_[static_cast<int>(entryType)];
|
||||
}
|
||||
|
||||
const PerformanceEntryBuffer &getBuffer(
|
||||
PerformanceEntryType entryType) const {
|
||||
return buffers_[static_cast<int>(entryType)];
|
||||
}
|
||||
|
||||
bool isReporting(PerformanceEntryType entryType) const {
|
||||
return reportingType_[static_cast<int>(entryType)];
|
||||
return getBuffer(entryType).isReporting;
|
||||
}
|
||||
|
||||
bool isReportingEvents() const {
|
||||
@@ -137,23 +145,13 @@ class PerformanceEntryReporter : public EventLogger {
|
||||
|
||||
private:
|
||||
std::optional<AsyncCallback<>> callback_;
|
||||
std::vector<RawPerformanceEntry> entries_;
|
||||
|
||||
std::mutex entriesMutex_;
|
||||
std::array<bool, (size_t)PerformanceEntryType::_COUNT> reportingType_{false};
|
||||
std::array<PerformanceEntryBuffer, NUM_PERFORMANCE_ENTRY_TYPES> buffers_;
|
||||
std::unordered_map<std::string, uint32_t> eventCounts_;
|
||||
std::array<double, (size_t)PerformanceEntryType::_COUNT> durationThreshold_{
|
||||
DEFAULT_DURATION_THRESHOLD};
|
||||
|
||||
// Mark registry for "measure" lookup
|
||||
PerformanceMarkRegistryType marksRegistry_;
|
||||
std::array<PerformanceMark, MARKS_BUFFER_SIZE> marksBuffer_;
|
||||
size_t marksBufferPosition_{0};
|
||||
size_t marksCount_{0};
|
||||
|
||||
std::array<PerformanceMeasure, MEASURES_BUFFER_SIZE> measuresBuffer_;
|
||||
size_t measuresBufferPosition_{0};
|
||||
size_t measuresCount_{0};
|
||||
|
||||
PerformanceEntryRegistryType marksRegistry_;
|
||||
uint32_t droppedEntryCount_{0};
|
||||
|
||||
struct EventEntry {
|
||||
@@ -171,49 +169,15 @@ class PerformanceEntryReporter : public EventLogger {
|
||||
|
||||
static EventTag sCurrentEventTag_;
|
||||
|
||||
PerformanceEntryReporter() {}
|
||||
PerformanceEntryReporter();
|
||||
|
||||
double getMarkTime(const std::string &markName) const;
|
||||
void scheduleFlushBuffer();
|
||||
|
||||
template <class T, size_t N>
|
||||
std::vector<RawPerformanceEntry> getCircularBufferContents(
|
||||
const std::array<T, N> &buffer,
|
||||
size_t entryCount,
|
||||
size_t bufferPosition,
|
||||
const char *entryName = nullptr) const {
|
||||
std::vector<RawPerformanceEntry> res;
|
||||
size_t pos = (bufferPosition - entryCount + buffer.size()) % buffer.size();
|
||||
for (size_t i = 0; i < entryCount; i++) {
|
||||
if (entryName == nullptr || buffer[pos].name == entryName) {
|
||||
res.push_back(buffer[pos].toRawPerformanceEntry());
|
||||
}
|
||||
pos = (pos + 1) % buffer.size();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class T, size_t N>
|
||||
void clearCircularBuffer(
|
||||
std::array<T, N> &buffer,
|
||||
size_t &entryCount,
|
||||
size_t &bufferPosition,
|
||||
const char *entryName) const {
|
||||
std::array<T, N> newBuffer;
|
||||
size_t newEntryCount = 0;
|
||||
|
||||
size_t pos = (bufferPosition - entryCount + buffer.size()) % buffer.size();
|
||||
for (size_t i = 0; i < entryCount; i++) {
|
||||
if (buffer[pos].name != entryName) {
|
||||
newBuffer[newEntryCount++] = buffer[pos];
|
||||
}
|
||||
pos = (pos + 1) % buffer.size();
|
||||
}
|
||||
|
||||
buffer = newBuffer;
|
||||
bufferPosition = newEntryCount;
|
||||
entryCount = newEntryCount;
|
||||
}
|
||||
void getEntries(
|
||||
PerformanceEntryType entryType,
|
||||
const char *entryName,
|
||||
std::vector<RawPerformanceEntry> &res) const;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
+14
-25
@@ -152,17 +152,6 @@ TEST(PerformanceEntryReporter, PerformanceEntryReporterTestReportMeasures) {
|
||||
|
||||
ASSERT_EQ(0, res.droppedEntriesCount);
|
||||
|
||||
ASSERT_STREQ("mark0", entries[0].name.c_str());
|
||||
ASSERT_STREQ("mark1", entries[1].name.c_str());
|
||||
ASSERT_STREQ("mark2", entries[2].name.c_str());
|
||||
ASSERT_STREQ("measure0", entries[3].name.c_str());
|
||||
ASSERT_STREQ("measure1", entries[4].name.c_str());
|
||||
ASSERT_STREQ("measure2", entries[5].name.c_str());
|
||||
ASSERT_STREQ("measure3", entries[6].name.c_str());
|
||||
ASSERT_STREQ("measure4", entries[7].name.c_str());
|
||||
|
||||
ASSERT_EQ(8, entries.size());
|
||||
|
||||
const std::vector<RawPerformanceEntry> expected = {
|
||||
{"mark0",
|
||||
static_cast<int>(PerformanceEntryType::MARK),
|
||||
@@ -171,20 +160,6 @@ TEST(PerformanceEntryReporter, PerformanceEntryReporterTestReportMeasures) {
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt},
|
||||
{"mark1",
|
||||
static_cast<int>(PerformanceEntryType::MARK),
|
||||
1.0,
|
||||
3.0,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt},
|
||||
{"mark2",
|
||||
static_cast<int>(PerformanceEntryType::MARK),
|
||||
2.0,
|
||||
4.0,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt},
|
||||
{"measure0",
|
||||
static_cast<int>(PerformanceEntryType::MEASURE),
|
||||
0.0,
|
||||
@@ -206,6 +181,13 @@ TEST(PerformanceEntryReporter, PerformanceEntryReporterTestReportMeasures) {
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt},
|
||||
{"mark1",
|
||||
static_cast<int>(PerformanceEntryType::MARK),
|
||||
1.0,
|
||||
3.0,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt},
|
||||
{"measure3",
|
||||
static_cast<int>(PerformanceEntryType::MEASURE),
|
||||
1.0,
|
||||
@@ -219,6 +201,13 @@ TEST(PerformanceEntryReporter, PerformanceEntryReporterTestReportMeasures) {
|
||||
0.5,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt},
|
||||
{"mark2",
|
||||
static_cast<int>(PerformanceEntryType::MARK),
|
||||
2.0,
|
||||
4.0,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt}};
|
||||
|
||||
ASSERT_EQ(expected, entries);
|
||||
|
||||
Reference in New Issue
Block a user