Skip to content

Commit

Permalink
Hoist responsibility for clearMarks/Measures to NativePerformanceObse…
Browse files Browse the repository at this point in the history
…rver (#36312)

Summary:
Pull Request resolved: #36312

## Changelog:

[Internal] -

`clearMarks` and `clearMeasures` methods are incidental to the `NativePerformance` TurboModule functionality, as in reality this responsibility belongs more on the `NativePerformanceObserver` and `PerformanceEntryReporter` side.

This is something that [the standard indirectly suggests](https://www.w3.org/TR/user-timing/#clearmarks-method) as well (referencing [performance entry buffer](https://www.w3.org/TR/performance-timeline/#dfn-performance-entry-buffer)).

The new implementation should be also a little bit more efficient, as it avoids calling the predicate for each entry.

Finally (and frankly, the main reason for this change, from my perspective), it will simplify mocking/testing the JS part of the PerfAPI code.

Reviewed By: rubennorte

Differential Revision: D43621174

fbshipit-source-id: c4217a0da1d8ecbce797240627f7b4f057d85b97
  • Loading branch information
rshest authored and facebook-github-bot committed Feb 28, 2023
1 parent 5112bc5 commit 14ab76a
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 69 deletions.
12 changes: 0 additions & 12 deletions Libraries/WebPerformance/NativePerformance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@ void NativePerformance::mark(
PerformanceEntryReporter::getInstance().mark(name, startTime, duration);
}

void NativePerformance::clearMarks(
jsi::Runtime &rt,
std::optional<std::string> markName) {
PerformanceEntryReporter::getInstance().clearMarks(markName);
}

void NativePerformance::measure(
jsi::Runtime &rt,
std::string name,
Expand All @@ -50,12 +44,6 @@ void NativePerformance::measure(
name, startTime, endTime, duration, startMark, endMark);
}

void NativePerformance::clearMeasures(
jsi::Runtime &rt,
std::optional<std::string> measureName) {
PerformanceEntryReporter::getInstance().clearMeasures(measureName);
}

std::unordered_map<std::string, double> NativePerformance::getSimpleMemoryInfo(
jsi::Runtime &rt) {
auto heapInfo = rt.instrumentation().getHeapInfo(false);
Expand Down
2 changes: 0 additions & 2 deletions Libraries/WebPerformance/NativePerformance.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class NativePerformance : public NativePerformanceCxxSpec<NativePerformance>,

void
mark(jsi::Runtime &rt, std::string name, double startTime, double duration);
void clearMarks(jsi::Runtime &rt, std::optional<std::string> markName);

void measure(
jsi::Runtime &rt,
Expand All @@ -37,7 +36,6 @@ class NativePerformance : public NativePerformanceCxxSpec<NativePerformance>,
std::optional<double> duration,
std::optional<std::string> startMark,
std::optional<std::string> endMark);
void clearMeasures(jsi::Runtime &rt, std::optional<std::string> measureName);

// To align with web API, we will make sure to return three properties
// (jsHeapSizeLimit, totalJSHeapSize, usedJSHeapSize) + anything needed from
Expand Down
3 changes: 0 additions & 3 deletions Libraries/WebPerformance/NativePerformance.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ export type NativeMemoryInfo = {[key: string]: number};

export interface Spec extends TurboModule {
+mark: (name: string, startTime: number, duration: number) => void;
+clearMarks: (markName?: string) => void;

+measure: (
name: string,
startTime: number,
Expand All @@ -26,7 +24,6 @@ export interface Spec extends TurboModule {
startMark?: string,
endMark?: string,
) => void;
+clearMeasures: (measureName?: string) => void;
+getSimpleMemoryInfo: () => NativeMemoryInfo;
}

Expand Down
9 changes: 9 additions & 0 deletions Libraries/WebPerformance/NativePerformanceObserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,13 @@ void NativePerformanceObserver::setDurationThreshold(
static_cast<PerformanceEntryType>(entryType), durationThreshold);
}

void NativePerformanceObserver::clearEntries(
jsi::Runtime &rt,
int32_t entryType,
std::optional<std::string> entryName) {
PerformanceEntryReporter::getInstance().clearEntries(
static_cast<PerformanceEntryType>(entryType),
entryName ? entryName->c_str() : nullptr);
}

} // namespace facebook::react
5 changes: 5 additions & 0 deletions Libraries/WebPerformance/NativePerformanceObserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ class NativePerformanceObserver
int32_t entryType,
double durationThreshold);

void clearEntries(
jsi::Runtime &rt,
int32_t entryType,
std::optional<std::string> entryName);

private:
};

Expand Down
4 changes: 4 additions & 0 deletions Libraries/WebPerformance/NativePerformanceObserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export interface Spec extends TurboModule {
entryType: RawPerformanceEntryType,
durationThreshold: number,
) => void;
+clearEntries: (
entryType: RawPerformanceEntryType,
entryName?: string,
) => void;
}

export default (TurboModuleRegistry.get<Spec>(
Expand Down
21 changes: 15 additions & 6 deletions Libraries/WebPerformance/Performance.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import warnOnce from '../Utilities/warnOnce';
import EventCounts from './EventCounts';
import MemoryInfo from './MemoryInfo';
import NativePerformance from './NativePerformance';
import NativePerformanceObserver from './NativePerformanceObserver';
import {PerformanceEntry} from './PerformanceEntry';
import {warnNoNativePerformanceObserver} from './PerformanceObserver';
import {RawPerformanceEntryTypeValues} from './RawPerformanceEntry';

type DetailType = mixed;

Expand Down Expand Up @@ -135,12 +138,15 @@ export default class Performance {
}

clearMarks(markName?: string): void {
if (!NativePerformance?.clearMarks) {
warnNoNativePerformance();
if (!NativePerformanceObserver?.clearEntries) {
warnNoNativePerformanceObserver();
return;
}

NativePerformance.clearMarks(markName);
NativePerformanceObserver?.clearEntries(
RawPerformanceEntryTypeValues.MARK,
markName,
);
}

measure(
Expand Down Expand Up @@ -213,12 +219,15 @@ export default class Performance {
}

clearMeasures(measureName?: string): void {
if (!NativePerformance?.clearMeasures) {
warnNoNativePerformance();
if (!NativePerformanceObserver?.clearEntries) {
warnNoNativePerformanceObserver();
return;
}

NativePerformance.clearMeasures(measureName);
NativePerformanceObserver?.clearEntries(
RawPerformanceEntryTypeValues.MEASURE,
measureName,
);
}

/**
Expand Down
62 changes: 19 additions & 43 deletions Libraries/WebPerformance/PerformanceEntryReporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,21 +121,27 @@ void PerformanceEntryReporter::mark(
std::nullopt});
}

void PerformanceEntryReporter::clearMarks(
const std::optional<std::string> &markName) {
if (markName) {
PerformanceMark mark{{*markName, 0}};
void PerformanceEntryReporter::clearEntries(
PerformanceEntryType entryType,
const char *entryName) {
if (entryName != nullptr && entryType == PerformanceEntryType::MARK) {
// remove a named mark from the mark/measure registry
PerformanceMark mark{{entryName, 0}};
marksRegistry_.erase(&mark);
clearEntries([&markName](const RawPerformanceEntry &entry) {
return entry.entryType == static_cast<int>(PerformanceEntryType::MARK) &&
entry.name == markName;
});
} else {
marksRegistry_.clear();
clearEntries([](const RawPerformanceEntry &entry) {
return entry.entryType == static_cast<int>(PerformanceEntryType::MARK);
});
}

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);
}

void PerformanceEntryReporter::measure(
Expand All @@ -158,22 +164,6 @@ void PerformanceEntryReporter::measure(
std::nullopt});
}

void PerformanceEntryReporter::clearMeasures(
const std::optional<std::string> &measureName) {
if (measureName) {
clearEntries([&measureName](const RawPerformanceEntry &entry) {
return entry.entryType ==
static_cast<int>(PerformanceEntryType::MEASURE) &&
entry.name == measureName;
});
} else {
marksRegistry_.clear();
clearEntries([](const RawPerformanceEntry &entry) {
return entry.entryType == static_cast<int>(PerformanceEntryType::MEASURE);
});
}
}

double PerformanceEntryReporter::getMarkTime(
const std::string &markName) const {
PerformanceMark mark{{std::move(markName), 0}};
Expand Down Expand Up @@ -202,20 +192,6 @@ void PerformanceEntryReporter::event(
interactionId});
}

void PerformanceEntryReporter::clearEntries(
std::function<bool(const RawPerformanceEntry &)> predicate) {
int lastPos = entries_.size() - 1;
int pos = lastPos;
while (pos >= 0) {
if (predicate(entries_[pos])) {
entries_[pos] = entries_[lastPos];
lastPos--;
}
pos--;
}
entries_.resize(lastPos + 1);
}

void PerformanceEntryReporter::scheduleFlushBuffer() {
if (callback_) {
callback_->callWithPriority(SchedulerPriority::IdlePriority);
Expand Down
7 changes: 4 additions & 3 deletions Libraries/WebPerformance/PerformanceEntryReporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ class PerformanceEntryReporter : public EventLogger {
}

void mark(const std::string &name, double startTime, double duration);
void clearMarks(const std::optional<std::string> &markName);

void measure(
const std::string &name,
Expand All @@ -93,7 +92,10 @@ class PerformanceEntryReporter : public EventLogger {
const std::optional<double> &duration,
const std::optional<std::string> &startMark,
const std::optional<std::string> &endMark);
void clearMeasures(const std::optional<std::string> &measureName);

void clearEntries(
PerformanceEntryType entryType,
const char *entryName = nullptr);

void event(
std::string name,
Expand All @@ -115,7 +117,6 @@ class PerformanceEntryReporter : public EventLogger {
PerformanceEntryReporter() {}

double getMarkTime(const std::string &markName) const;
void clearEntries(std::function<bool(const RawPerformanceEntry &)> predicate);
void scheduleFlushBuffer();

bool isReportingEvents() const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ const NativePerformanceObserverMock: NativePerformanceObserver = {
) => {
durationThresholds.set(entryType, durationThreshold);
},

clearEntries: (entryType: RawPerformanceEntryType, entryName?: string) => {
entries = entries.filter(
e =>
e.entryType === entryType &&
(entryName == null || e.name === entryName),
);
},
};

export default NativePerformanceObserverMock;

0 comments on commit 14ab76a

Please sign in to comment.