Skip to content

Commit 1f7374c

Browse files
Mizuchimeta-codesync[bot]
authored andcommitted
Add method to apply patch to serialized data without extracting the mask
Summary: Today we extract read/write mask from patch, so that we partially materialize the data. This is not always fast (one reason is that the implementation of extracting mask is slow and there is a room to optimize). Let's create another version to apply mask directly. ``` $ buck run mode/opt fbcode//thrift/lib/cpp2/protocol:patch_and_mask_bench Executing actions. Remaining 0/23 1:13.8s exec time total Command: run. Finished 10 local, 1 remote Time elapsed: 35.6s BUILD SUCCEEDED - starting your binary ============================================================================ [...]plyPatchToSerializedDataBenchmark.cpp relative time/iter iters/s ============================================================================ few_small_fields 169.56us 5.90K few_small_fields_partial_deser 10158.% 1.67us 599.05K large_fields 345.91us 2.89K large_fields_partial_deser 114.01% 303.41us 3.30K all_small_fields 2.28ms 438.14 all_small_fields_partial_deser 18.884% 12.09ms 82.74 clear_large_fields 114.54us 8.73K clear_large_fields_partial_deser 114.60% 99.95us 10.01K few_map_elems_with_put 2.49ms 401.22 few_map_elems_with_put_partial_deser 37.184% 6.70ms 149.19 all_map_elems_with_put 8.16ms 122.53 all_map_elems_with_put_partial_deser 49.702% 16.42ms 60.90 few_map_elems_with_patch_after 2.60ms 385.04 few_map_elems_with_patch_after_partial_deser 38.937% 6.67ms 149.92 all_map_elems_with_patch_after 15.48ms 64.60 all_map_elems_with_patch_after_partial_deser 36.874% 41.98ms 23.82 ``` Reviewed By: pranavtbhat Differential Revision: D86915691 fbshipit-source-id: d6234e1cf8993c64b0a28aa23808bffd765a1504
1 parent f661625 commit 1f7374c

3 files changed

Lines changed: 46 additions & 24 deletions

File tree

third-party/thrift/src/thrift/lib/cpp2/protocol/ApplyPatchToSerializedDataBenchmark.cpp

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -227,75 +227,75 @@ void init(int n) {
227227
patch8 = getPatch8(n);
228228
}
229229

230-
void runOriginalApproach(
231-
std::unique_ptr<folly::IOBuf>& serialized, const DynamicPatch& patch) {
232-
Value value;
233-
value.emplace_object(parseObject<CompactProtocolReader>(*serialized));
234-
patch.apply(value);
235-
protocol::serializeObject<CompactProtocolWriter>(value.as_object());
236-
}
237-
238230
BENCHMARK(few_small_fields) {
239-
runOriginalApproach(serialized1, patch1);
231+
patch1.applyToSerializedObjectWithoutExtractingMask<
232+
type::StandardProtocol::Compact>(*serialized1);
240233
}
241234

242-
BENCHMARK(few_small_fields_partial_deser) {
235+
BENCHMARK_RELATIVE(few_small_fields_partial_deser) {
243236
patch1.applyToSerializedObject<type::StandardProtocol::Compact>(*serialized1);
244237
}
245238

246239
BENCHMARK(large_fields) {
247-
runOriginalApproach(serialized2, patch2);
240+
patch2.applyToSerializedObjectWithoutExtractingMask<
241+
type::StandardProtocol::Compact>(*serialized2);
248242
}
249243

250-
BENCHMARK(large_fields_partial_deser) {
244+
BENCHMARK_RELATIVE(large_fields_partial_deser) {
251245
patch2.applyToSerializedObject<type::StandardProtocol::Compact>(*serialized2);
252246
}
253247

254248
BENCHMARK(all_small_fields) {
255-
runOriginalApproach(serialized3, patch3);
249+
patch3.applyToSerializedObjectWithoutExtractingMask<
250+
type::StandardProtocol::Compact>(*serialized3);
256251
}
257252

258-
BENCHMARK(all_small_fields_partial_deser) {
253+
BENCHMARK_RELATIVE(all_small_fields_partial_deser) {
259254
patch3.applyToSerializedObject<type::StandardProtocol::Compact>(*serialized3);
260255
}
261256

262257
BENCHMARK(clear_large_fields) {
263-
runOriginalApproach(serialized4, patch4);
258+
patch4.applyToSerializedObjectWithoutExtractingMask<
259+
type::StandardProtocol::Compact>(*serialized4);
264260
}
265261

266-
BENCHMARK(clear_large_fields_partial_deser) {
262+
BENCHMARK_RELATIVE(clear_large_fields_partial_deser) {
267263
patch4.applyToSerializedObject<type::StandardProtocol::Compact>(*serialized4);
268264
}
269265

270266
BENCHMARK(few_map_elems_with_put) {
271-
runOriginalApproach(serialized5, patch5);
267+
patch5.applyToSerializedObjectWithoutExtractingMask<
268+
type::StandardProtocol::Compact>(*serialized5);
272269
}
273270

274-
BENCHMARK(few_map_elems_with_put_partial_deser) {
271+
BENCHMARK_RELATIVE(few_map_elems_with_put_partial_deser) {
275272
patch5.applyToSerializedObject<type::StandardProtocol::Compact>(*serialized5);
276273
}
277274

278275
BENCHMARK(all_map_elems_with_put) {
279-
runOriginalApproach(serialized6, patch6);
276+
patch6.applyToSerializedObjectWithoutExtractingMask<
277+
type::StandardProtocol::Compact>(*serialized6);
280278
}
281279

282-
BENCHMARK(all_map_elems_with_put_partial_deser) {
280+
BENCHMARK_RELATIVE(all_map_elems_with_put_partial_deser) {
283281
patch6.applyToSerializedObject<type::StandardProtocol::Compact>(*serialized6);
284282
}
285283

286284
BENCHMARK(few_map_elems_with_patch_after) {
287-
runOriginalApproach(serialized7, patch7);
285+
patch7.applyToSerializedObjectWithoutExtractingMask<
286+
type::StandardProtocol::Compact>(*serialized7);
288287
}
289288

290-
BENCHMARK(few_map_elems_with_patch_after_partial_deser) {
289+
BENCHMARK_RELATIVE(few_map_elems_with_patch_after_partial_deser) {
291290
patch7.applyToSerializedObject<type::StandardProtocol::Compact>(*serialized7);
292291
}
293292

294293
BENCHMARK(all_map_elems_with_patch_after) {
295-
runOriginalApproach(serialized8, patch8);
294+
patch8.applyToSerializedObjectWithoutExtractingMask<
295+
type::StandardProtocol::Compact>(*serialized8);
296296
}
297297

298-
BENCHMARK(all_map_elems_with_patch_after_partial_deser) {
298+
BENCHMARK_RELATIVE(all_map_elems_with_patch_after_partial_deser) {
299299
patch8.applyToSerializedObject<type::StandardProtocol::Compact>(*serialized8);
300300
}
301301

third-party/thrift/src/thrift/lib/thrift/detail/DynamicPatch.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,10 +1998,26 @@ std::unique_ptr<folly::IOBuf> DynamicPatch::applyToSerializedObject(
19981998
return serializeObject<ProtocolWriter>(val.as_object(), result.excluded);
19991999
}
20002000

2001+
template <type::StandardProtocol Protocol>
2002+
std::unique_ptr<folly::IOBuf>
2003+
DynamicPatch::applyToSerializedObjectWithoutExtractingMask(
2004+
const folly::IOBuf& buf) const {
2005+
protocol::Value val;
2006+
val.emplace_object(parseObject<ProtocolReaderFor<Protocol>>(buf));
2007+
apply(val);
2008+
return serializeObject<ProtocolWriterFor<Protocol>>(val.as_object());
2009+
}
2010+
20012011
template std::unique_ptr<folly::IOBuf> DynamicPatch::applyToSerializedObject<
20022012
type::StandardProtocol::Binary>(const folly::IOBuf& buf) const;
20032013
template std::unique_ptr<folly::IOBuf> DynamicPatch::applyToSerializedObject<
20042014
type::StandardProtocol::Compact>(const folly::IOBuf& buf) const;
2015+
template std::unique_ptr<folly::IOBuf>
2016+
DynamicPatch::applyToSerializedObjectWithoutExtractingMask<
2017+
type::StandardProtocol::Binary>(const folly::IOBuf& buf) const;
2018+
template std::unique_ptr<folly::IOBuf>
2019+
DynamicPatch::applyToSerializedObjectWithoutExtractingMask<
2020+
type::StandardProtocol::Compact>(const folly::IOBuf& buf) const;
20052021

20062022
Object DynamicPatch::toObject() && {
20072023
return std::visit([&](auto&& v) { return std::move(v).toObject(); }, *patch_);

third-party/thrift/src/thrift/lib/thrift/detail/DynamicPatch.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,12 @@ class DynamicPatch {
509509
std::unique_ptr<folly::IOBuf> applyToSerializedObject(
510510
const folly::IOBuf& buf) const;
511511

512+
/// The behavior is identical to applyToSerializedObject(...), though
513+
/// sometimes it's faster to deserialize the whole iobuf then apply patches.
514+
template <type::StandardProtocol Protocol>
515+
std::unique_ptr<folly::IOBuf> applyToSerializedObjectWithoutExtractingMask(
516+
const folly::IOBuf& buf) const;
517+
512518
/// Converts SafePatch stored in Thrift Any to DynamicPatch.
513519
[[nodiscard]] static DynamicPatch fromSafePatch(const type::AnyStruct& any);
514520
/// Stores DynamicPatch as SafePatch in Thrift Any with the provided type

0 commit comments

Comments
 (0)