Skip to content

Commit 75d6cb1

Browse files
hoxyqfacebook-github-bot
authored andcommitted
Avoid copies when dispatching TraceEvent chunks (#52868)
Summary: Pull Request resolved: #52868 # Changelog: [Internal] Mainly, 2 changes: - Callback that emits `Tracing.dataCollected` events will receive chunks as rvalues refs (`&&`), instead of `const &`. - The RuntimeSamplingProfile will be passed to the serializer as rvalue ref. Reviewed By: huntie Differential Revision: D78919223 fbshipit-source-id: 7f65e0627c8839d507e6b2d088fdb0b560906b6a
1 parent 3cf11a3 commit 75d6cb1

File tree

6 files changed

+39
-36
lines changed

6 files changed

+39
-36
lines changed

packages/react-native/ReactCommon/jsinspector-modern/TracingAgent.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,10 @@ bool TracingAgent::handleRequest(const cdp::PreparsedRequest& req) {
102102
// Send response to Tracing.end request.
103103
frontendChannel_(cdp::jsonResult(req.id));
104104

105-
auto dataCollectedCallback = [this](const folly::dynamic& eventsChunk) {
105+
auto dataCollectedCallback = [this](folly::dynamic&& eventsChunk) {
106106
frontendChannel_(cdp::jsonNotification(
107107
"Tracing.dataCollected",
108-
folly::dynamic::object("value", eventsChunk)));
108+
folly::dynamic::object("value", std::move(eventsChunk))));
109109
};
110110
performanceTracer.collectEvents(
111111
dataCollectedCallback, TRACE_EVENT_CHUNK_SIZE);
@@ -114,8 +114,9 @@ bool TracingAgent::handleRequest(const cdp::PreparsedRequest& req) {
114114
performanceTracer,
115115
dataCollectedCallback,
116116
PROFILE_TRACE_EVENT_CHUNK_SIZE);
117+
auto tracingProfile = instanceAgent_->collectTracingProfile();
117118
serializer.serializeAndNotify(
118-
instanceAgent_->collectTracingProfile().runtimeSamplingProfile,
119+
std::move(tracingProfile.runtimeSamplingProfile),
119120
instanceTracingStartTimestamp_);
120121

121122
frontendChannel_(cdp::jsonNotification(

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ bool PerformanceTracer::stopTracing() {
8383
}
8484

8585
void PerformanceTracer::collectEvents(
86-
const std::function<void(const folly::dynamic& eventsChunk)>&
87-
resultCallback,
86+
const std::function<void(folly::dynamic&& eventsChunk)>& resultCallback,
8887
uint16_t chunkSize) {
8988
std::vector<TraceEvent> localBuffer;
9089
{
@@ -102,12 +101,12 @@ void PerformanceTracer::collectEvents(
102101
serializedTraceEvents.push_back(serializeTraceEvent(std::move(event)));
103102

104103
if (serializedTraceEvents.size() == chunkSize) {
105-
resultCallback(serializedTraceEvents);
104+
resultCallback(std::move(serializedTraceEvents));
106105
serializedTraceEvents = folly::dynamic::array();
107106
}
108107
}
109108
if (!serializedTraceEvents.empty()) {
110-
resultCallback(serializedTraceEvents);
109+
resultCallback(std::move(serializedTraceEvents));
111110
}
112111
}
113112

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ class PerformanceTracer {
5656
* Flush out buffered CDP Trace Events using the given callback.
5757
*/
5858
void collectEvents(
59-
const std::function<void(const folly::dynamic& eventsChunk)>&
60-
resultCallback,
59+
const std::function<void(folly::dynamic&& eventsChunk)>& resultCallback,
6160
uint16_t chunkSize);
6261

6362
/**

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

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ void RuntimeSamplingProfileTraceEventSerializer::chunkEmptySample(
115115
}
116116

117117
void RuntimeSamplingProfileTraceEventSerializer::bufferProfileChunkTraceEvent(
118-
ProfileChunk& chunk,
118+
ProfileChunk&& chunk,
119119
uint16_t profileId) {
120120
if (chunk.isEmpty()) {
121121
return;
@@ -135,14 +135,17 @@ void RuntimeSamplingProfileTraceEventSerializer::bufferProfileChunkTraceEvent(
135135
TraceEventProfileChunk{
136136
.cpuProfile =
137137
TraceEventProfileChunk::CPUProfile{
138-
traceEventNodes, chunk.samples},
138+
.nodes = std::move(traceEventNodes),
139+
.samples = std::move(chunk.samples)},
139140
.timeDeltas =
140-
TraceEventProfileChunk::TimeDeltas{chunk.timeDeltas},
141+
TraceEventProfileChunk::TimeDeltas{
142+
.deltas = std::move(chunk.timeDeltas),
143+
},
141144
}));
142145
}
143146

144147
void RuntimeSamplingProfileTraceEventSerializer::processCallStack(
145-
const std::vector<RuntimeSamplingProfile::SampleCallStackFrame>& callStack,
148+
std::vector<RuntimeSamplingProfile::SampleCallStackFrame>&& callStack,
146149
ProfileChunk& chunk,
147150
ProfileTreeNode& rootNode,
148151
uint32_t idleNodeId,
@@ -184,14 +187,16 @@ void RuntimeSamplingProfileTraceEventSerializer::processCallStack(
184187

185188
void RuntimeSamplingProfileTraceEventSerializer::
186189
sendBufferedTraceEventsAndClear() {
187-
notificationCallback_(traceEventBuffer_);
190+
notificationCallback_(std::move(traceEventBuffer_));
191+
188192
traceEventBuffer_ = folly::dynamic::array();
193+
traceEventBuffer_.reserve(traceEventChunkSize_);
189194
}
190195

191196
void RuntimeSamplingProfileTraceEventSerializer::serializeAndNotify(
192-
const RuntimeSamplingProfile& profile,
197+
RuntimeSamplingProfile&& profile,
193198
HighResTimeStamp tracingStartTime) {
194-
const std::vector<RuntimeSamplingProfile::Sample>& samples = profile.samples;
199+
auto samples = std::move(profile.samples);
195200
if (samples.empty()) {
196201
return;
197202
}
@@ -225,7 +230,7 @@ void RuntimeSamplingProfileTraceEventSerializer::serializeAndNotify(
225230
chunk.nodes.push_back(*idleNode);
226231
uint32_t idleNodeId = idleNode->getId();
227232

228-
for (const auto& sample : samples) {
233+
for (auto& sample : samples) {
229234
uint64_t currentSampleThreadId = sample.threadId;
230235
auto currentSampleTimestamp = getHighResTimeStampForSample(sample);
231236

@@ -234,7 +239,7 @@ void RuntimeSamplingProfileTraceEventSerializer::serializeAndNotify(
234239
// We should group samples by thread id once we support executing JavaScript
235240
// on different threads.
236241
if (currentSampleThreadId != chunk.threadId || chunk.isFull()) {
237-
bufferProfileChunkTraceEvent(chunk, PROFILE_ID);
242+
bufferProfileChunkTraceEvent(std::move(chunk), PROFILE_ID);
238243
chunk = ProfileChunk{
239244
profileChunkSize_, currentSampleThreadId, currentChunkTimestamp};
240245
}
@@ -244,7 +249,7 @@ void RuntimeSamplingProfileTraceEventSerializer::serializeAndNotify(
244249
}
245250

246251
processCallStack(
247-
sample.callStack,
252+
std::move(sample.callStack),
248253
chunk,
249254
rootNode,
250255
idleNodeId,
@@ -255,7 +260,7 @@ void RuntimeSamplingProfileTraceEventSerializer::serializeAndNotify(
255260
}
256261

257262
if (!chunk.isEmpty()) {
258-
bufferProfileChunkTraceEvent(chunk, PROFILE_ID);
263+
bufferProfileChunkTraceEvent(std::move(chunk), PROFILE_ID);
259264
}
260265

261266
if (!traceEventBuffer_.empty()) {

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class RuntimeSamplingProfileTraceEventSerializer {
7272
*/
7373
RuntimeSamplingProfileTraceEventSerializer(
7474
PerformanceTracer& performanceTracer,
75-
std::function<void(const folly::dynamic& traceEventsChunk)>
75+
std::function<void(folly::dynamic&& traceEventsChunk)>
7676
notificationCallback,
7777
uint16_t traceEventChunkSize,
7878
uint16_t profileChunkSize = 10)
@@ -90,7 +90,7 @@ class RuntimeSamplingProfileTraceEventSerializer {
9090
* will be used as a starting reference point of JavaScript samples recording.
9191
*/
9292
void serializeAndNotify(
93-
const RuntimeSamplingProfile& profile,
93+
RuntimeSamplingProfile&& profile,
9494
HighResTimeStamp tracingStartTime);
9595

9696
private:
@@ -123,7 +123,7 @@ class RuntimeSamplingProfileTraceEventSerializer {
123123
* \param chunk The chunk that will be buffered.
124124
* \param profileId The id of the Profile.
125125
*/
126-
void bufferProfileChunkTraceEvent(ProfileChunk& chunk, uint16_t profileId);
126+
void bufferProfileChunkTraceEvent(ProfileChunk&& chunk, uint16_t profileId);
127127

128128
/**
129129
* Encapsulates logic for processing the call stack of the sample.
@@ -140,8 +140,7 @@ class RuntimeSamplingProfileTraceEventSerializer {
140140
* generating unique node ids.
141141
*/
142142
void processCallStack(
143-
const std::vector<RuntimeSamplingProfile::SampleCallStackFrame>&
144-
callStack,
143+
std::vector<RuntimeSamplingProfile::SampleCallStackFrame>&& callStack,
145144
ProfileChunk& chunk,
146145
ProfileTreeNode& rootNode,
147146
uint32_t idleNodeId,
@@ -154,10 +153,10 @@ class RuntimeSamplingProfileTraceEventSerializer {
154153
void sendBufferedTraceEventsAndClear();
155154

156155
PerformanceTracer& performanceTracer_;
157-
const std::function<void(const folly::dynamic& traceEventsChunk)>
156+
const std::function<void(folly::dynamic&& traceEventsChunk)>
158157
notificationCallback_;
159-
uint16_t traceEventChunkSize_;
160-
uint16_t profileChunkSize_;
158+
const uint16_t traceEventChunkSize_;
159+
const uint16_t profileChunkSize_;
161160

162161
folly::dynamic traceEventBuffer_;
163162
};

packages/react-native/ReactCommon/jsinspector-modern/tracing/tests/RuntimeSamplingProfileTraceEventSerializerTest.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ class RuntimeSamplingProfileTraceEventSerializerTest : public ::testing::Test {
1818
protected:
1919
std::vector<folly::dynamic> notificationEvents_;
2020

21-
std::function<void(const folly::dynamic& traceEventsChunk)>
21+
std::function<void(folly::dynamic&& traceEventsChunk)>
2222
createNotificationCallback() {
23-
return [this](const folly::dynamic& traceEventsChunk) {
23+
return [this](folly::dynamic&& traceEventsChunk) {
2424
notificationEvents_.push_back(traceEventsChunk);
2525
};
2626
}
@@ -74,7 +74,7 @@ TEST_F(RuntimeSamplingProfileTraceEventSerializerTest, EmptyProfile) {
7474
auto tracingStartTime = HighResTimeStamp::now();
7575

7676
// Execute
77-
serializer.serializeAndNotify(profile, tracingStartTime);
77+
serializer.serializeAndNotify(std::move(profile), tracingStartTime);
7878

7979
// Nothing should be reported if the profile is empty.
8080
EXPECT_TRUE(notificationEvents_.empty());
@@ -122,7 +122,7 @@ TEST_F(
122122
auto tracingStartTime = HighResTimeStamp::now();
123123

124124
// Execute
125-
serializer.serializeAndNotify(profile, tracingStartTime);
125+
serializer.serializeAndNotify(std::move(profile), tracingStartTime);
126126

127127
// Verify
128128
ASSERT_EQ(notificationEvents_.size(), 2);
@@ -155,7 +155,7 @@ TEST_F(RuntimeSamplingProfileTraceEventSerializerTest, EmptySample) {
155155
folly::dynamic chunkEvent = folly::dynamic::object;
156156

157157
// Execute
158-
serializer.serializeAndNotify(profile, tracingStartTime);
158+
serializer.serializeAndNotify(std::move(profile), tracingStartTime);
159159

160160
// Verify
161161
// [["Profile"], ["ProfileChunk"]]
@@ -192,7 +192,7 @@ TEST_F(
192192
auto tracingStartTime = HighResTimeStamp::now();
193193

194194
// Execute
195-
serializer.serializeAndNotify(profile, tracingStartTime);
195+
serializer.serializeAndNotify(std::move(profile), tracingStartTime);
196196

197197
// [["Profile"], ["ProfileChunk", "ProfileChunk", "ProfileChunk]]
198198
// Samples from different thread should never be grouped together in the same
@@ -231,7 +231,7 @@ TEST_F(
231231
auto tracingStartTime = HighResTimeStamp::now();
232232

233233
// Execute
234-
serializer.serializeAndNotify(profile, tracingStartTime);
234+
serializer.serializeAndNotify(std::move(profile), tracingStartTime);
235235

236236
// [["Profile"], ["ProfileChunk", "ProfileChunk"], ["ProfileChunk"]]
237237
ASSERT_EQ(notificationEvents_.size(), 3);
@@ -272,7 +272,7 @@ TEST_F(RuntimeSamplingProfileTraceEventSerializerTest, ProfileChunkSizeLimit) {
272272
auto tracingStartTime = HighResTimeStamp::now();
273273

274274
// Execute
275-
serializer.serializeAndNotify(profile, tracingStartTime);
275+
serializer.serializeAndNotify(std::move(profile), tracingStartTime);
276276

277277
// [["Profile"], ["ProfileChunk", "ProfileChunk", "ProfileChunk"]]
278278
ASSERT_EQ(notificationEvents_.size(), 2);

0 commit comments

Comments
 (0)