mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Performance.measure: handle the case with a single startMark argument correctly (#37888)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37888 # Changelog: [Internal] - There was one particular permutation of input arguments to `Performance.measure` that wasn't handled correctly on the native side, namely when there is only the start mark argument present, but not the end time/mark, e.g.: ``` Performance.measure('myMeasure', 'someStartMark'); ``` In this case, [according to the standard](https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure), the end time should be taken as the current one: > The end timestamp is one of: > ... > -the value returned by Performance.now(), if no end mark is specified or can be determined from other values. It was taken as 0 instead, making the total duration negative and consequently getting it filtered out by the default `durationThreshold` of 0. I've added a corresponding missing clause in the native unit tests. This also required a slight extension to the `PerformanceObserver` API to allow for mocking the current timestamp provider. Reviewed By: rubennorte Differential Revision: D46728261 fbshipit-source-id: bd904d9c93707fa04c1a0ddb30802691e253c106
This commit is contained in:
committed by
Facebook GitHub Bot
parent
377a8b70ee
commit
44755726ed
@@ -15,10 +15,6 @@
|
||||
namespace facebook::react {
|
||||
EventTag PerformanceEntryReporter::sCurrentEventTag_{0};
|
||||
|
||||
static inline double getCurrentTimeStamp() {
|
||||
return JSExecutor::performanceNow();
|
||||
}
|
||||
|
||||
PerformanceEntryReporter &PerformanceEntryReporter::getInstance() {
|
||||
static PerformanceEntryReporter instance;
|
||||
return instance;
|
||||
@@ -29,11 +25,17 @@ PerformanceEntryReporter::PerformanceEntryReporter() {
|
||||
// sure that marks can be referenced by measures
|
||||
getBuffer(PerformanceEntryType::MARK).hasNameLookup = true;
|
||||
}
|
||||
|
||||
void PerformanceEntryReporter::setReportingCallback(
|
||||
std::optional<AsyncCallback<>> callback) {
|
||||
callback_ = callback;
|
||||
}
|
||||
|
||||
double PerformanceEntryReporter::getCurrentTimeStamp() const {
|
||||
return timeStampProvider_ != nullptr ? timeStampProvider_()
|
||||
: JSExecutor::performanceNow();
|
||||
}
|
||||
|
||||
void PerformanceEntryReporter::startReporting(PerformanceEntryType entryType) {
|
||||
auto &buffer = getBuffer(entryType);
|
||||
buffer.isReporting = true;
|
||||
@@ -219,7 +221,15 @@ void PerformanceEntryReporter::measure(
|
||||
const std::optional<std::string> &endMark) {
|
||||
double startTimeVal = startMark ? getMarkTime(*startMark) : startTime;
|
||||
double endTimeVal = endMark ? getMarkTime(*endMark) : endTime;
|
||||
|
||||
if (!endMark && endTime < startTimeVal) {
|
||||
// The end time is not specified, take the current time, according to the
|
||||
// standard
|
||||
endTimeVal = getCurrentTimeStamp();
|
||||
}
|
||||
|
||||
double durationVal = duration ? *duration : endTimeVal - startTimeVal;
|
||||
|
||||
logEntry(
|
||||
{name,
|
||||
static_cast<int>(PerformanceEntryType::MEASURE),
|
||||
|
||||
@@ -147,6 +147,10 @@ class PerformanceEntryReporter : public EventLogger {
|
||||
return eventCounts_;
|
||||
}
|
||||
|
||||
void setTimeStampProvider(std::function<double()> provider) {
|
||||
timeStampProvider_ = provider;
|
||||
}
|
||||
|
||||
private:
|
||||
std::optional<AsyncCallback<>> callback_;
|
||||
|
||||
@@ -171,6 +175,8 @@ class PerformanceEntryReporter : public EventLogger {
|
||||
std::unordered_map<EventTag, EventEntry> eventsInFlight_;
|
||||
std::mutex eventsInFlightMutex_;
|
||||
|
||||
std::function<double()> timeStampProvider_ = nullptr;
|
||||
|
||||
static EventTag sCurrentEventTag_;
|
||||
|
||||
PerformanceEntryReporter();
|
||||
@@ -182,6 +188,8 @@ class PerformanceEntryReporter : public EventLogger {
|
||||
PerformanceEntryType entryType,
|
||||
const char *entryName,
|
||||
std::vector<RawPerformanceEntry> &res) const;
|
||||
|
||||
double getCurrentTimeStamp() const;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
+12
-2
@@ -146,8 +146,11 @@ TEST(PerformanceEntryReporter, PerformanceEntryReporterTestReportMeasures) {
|
||||
reporter.measure("measure3", 0.0, 0.0, 5.0, "mark1");
|
||||
reporter.measure("measure4", 1.5, 0.0, std::nullopt, std::nullopt, "mark2");
|
||||
|
||||
reporter.setTimeStampProvider([]() { return 3.5; });
|
||||
reporter.measure("measure5", 0.0, 0.0, std::nullopt, "mark2");
|
||||
|
||||
reporter.mark("mark3", 2.0);
|
||||
reporter.measure("measure5", 2.0, 2.0);
|
||||
reporter.measure("measure6", 2.0, 2.0);
|
||||
reporter.mark("mark4", 2.0);
|
||||
|
||||
auto res = reporter.popPendingEntries();
|
||||
@@ -226,13 +229,20 @@ TEST(PerformanceEntryReporter, PerformanceEntryReporterTestReportMeasures) {
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt},
|
||||
{"measure5",
|
||||
{"measure6",
|
||||
static_cast<int>(PerformanceEntryType::MEASURE),
|
||||
2.0,
|
||||
0.0,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt},
|
||||
{"measure5",
|
||||
static_cast<int>(PerformanceEntryType::MEASURE),
|
||||
2.0,
|
||||
1.5,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt},
|
||||
};
|
||||
|
||||
ASSERT_EQ(expected, entries);
|
||||
|
||||
Reference in New Issue
Block a user