Skip to content

Commit 5aaa3c3

Browse files
committed
Avoid copying strings when serializing TraceEvent / lock only on buffer operations (facebook#52220)
Summary: Pull Request resolved: facebook#52220 # Changelog: [Internal] Mainly, 2 changes: 1. `PerformanceTracer::serializeTraceEvent(const TraceEvent& event)` -> `PerformanceTracer::serializeTraceEvent(TraceEvent&& event)` for less copies, actually move strings from the `TraceEvent` into the serialized `folly:object`. 2. When collecting events from the buffer, only lock when accessing buffer, not when serializing. Reviewed By: rubennorte Differential Revision: D77164969
1 parent 1bdfb9b commit 5aaa3c3

File tree

2 files changed

+28
-17
lines changed

2 files changed

+28
-17
lines changed

packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,27 +87,32 @@ void PerformanceTracer::collectEvents(
8787
const std::function<void(const folly::dynamic& eventsChunk)>&
8888
resultCallback,
8989
uint16_t chunkSize) {
90-
std::lock_guard lock(tracingMutex_);
90+
std::vector<TraceEvent> localBuffer;
91+
{
92+
std::lock_guard lock(tracingMutex_);
93+
// NOTE: This doesn't guarantee to preserve the capacity of the buffer.
94+
// Right now we are not specifying it explicitly, but we would have to do it
95+
// in the future, once we decide to display the buffer usage in the UI.
96+
buffer_.swap(localBuffer);
97+
}
9198

92-
if (buffer_.empty()) {
99+
if (localBuffer.empty()) {
93100
return;
94101
}
95102

96-
auto traceEvents = folly::dynamic::array();
97-
for (const auto& event : buffer_) {
103+
auto serializedTraceEvents = folly::dynamic::array();
104+
for (auto&& event : localBuffer) {
98105
// Emit trace events
99-
traceEvents.push_back(serializeTraceEvent(event));
106+
serializedTraceEvents.push_back(serializeTraceEvent(std::move(event)));
100107

101-
if (traceEvents.size() == chunkSize) {
102-
resultCallback(traceEvents);
103-
traceEvents = folly::dynamic::array();
108+
if (serializedTraceEvents.size() == chunkSize) {
109+
resultCallback(serializedTraceEvents);
110+
serializedTraceEvents = folly::dynamic::array();
104111
}
105112
}
106-
if (!traceEvents.empty()) {
107-
resultCallback(traceEvents);
113+
if (!serializedTraceEvents.empty()) {
114+
resultCallback(serializedTraceEvents);
108115
}
109-
110-
buffer_.clear();
111116
}
112117

113118
void PerformanceTracer::reportMark(
@@ -326,21 +331,21 @@ folly::dynamic PerformanceTracer::getSerializedRuntimeProfileChunkTraceEvent(
326331
}
327332

328333
folly::dynamic PerformanceTracer::serializeTraceEvent(
329-
const TraceEvent& event) const {
334+
TraceEvent&& event) const {
330335
folly::dynamic result = folly::dynamic::object;
331336

332337
if (event.id.has_value()) {
333338
std::array<char, 16> buffer{};
334339
snprintf(buffer.data(), buffer.size(), "0x%x", event.id.value());
335340
result["id"] = buffer.data();
336341
}
337-
result["name"] = event.name;
338-
result["cat"] = event.cat;
342+
result["name"] = std::move(event.name);
343+
result["cat"] = std::move(event.cat);
339344
result["ph"] = std::string(1, event.ph);
340345
result["ts"] = highResTimeStampToTracingClockTimeStamp(event.ts);
341346
result["pid"] = event.pid;
342347
result["tid"] = event.tid;
343-
result["args"] = event.args;
348+
result["args"] = std::move(event.args);
344349
if (event.dur.has_value()) {
345350
result["dur"] = highResDurationToTracingClockDuration(event.dur.value());
346351
}

packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,13 @@ class PerformanceTracer {
132132
PerformanceTracer& operator=(const PerformanceTracer&) = delete;
133133
~PerformanceTracer() = default;
134134

135-
folly::dynamic serializeTraceEvent(const TraceEvent& event) const;
135+
/**
136+
* Serialize a TraceEvent into a folly::dynamic object.
137+
* \param event rvalue reference to the TraceEvent object.
138+
* \return folly::dynamic object that represents a serialized into JSON Trace
139+
* Event for CDP.
140+
*/
141+
folly::dynamic serializeTraceEvent(TraceEvent&& event) const;
136142

137143
uint64_t processId_;
138144

0 commit comments

Comments
 (0)