2 * Copyright (c) Meta Platforms, Inc. and affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <folly/Benchmark.h>
20 #include <folly/Traits.h>
21 #include <folly/init/Init.h>
22 #include <folly/lang/Pretty.h>
23 #include <thrift/lib/cpp2/protocol/Serializer.h>
24 #include <thrift/test/benchmarks/gen-cpp2/terse_write_benchmark_types.h>
26 namespace apache::thrift::test
{
29 constexpr int kIterationCount
= 1'000'000;
33 op::for_each_field_id
<T
>([&obj
](auto id
) { op::get
<>(id
, obj
) = 1; });
36 void fill_half(T
& obj
) {
38 op::for_each_field_id
<T
>([&obj
, &pass
](auto id
) {
39 if (pass
= !pass
, pass
) {
40 op::get
<>(id
, obj
) = 1;
45 void fill_first(T
& obj
) {
46 op::get
<>(field_id
<1>{}, obj
) = 1;
49 void fill_middle(T
& obj
) {
50 op::get
<>(field_id
<op::size_v
<T
> / 2 + 1>{}, obj
) = 1;
53 void fill_last(T
& obj
) {
54 op::get
<>(field_id
<op::size_v
<T
>>{}, obj
) = 1;
57 template <class Struct
>
58 void add_benchmark(bool empty
= false) {
59 std::string name
= folly::pretty_name
<Struct
>();
60 name
= name
.substr(name
.rfind("::") + 2) + (empty
? "_empty" : "");
62 folly::addBenchmark(__FILE__
, name
, [&] {
64 for (int i
= 0; i
< kIterationCount
; i
++) {
65 auto s
= CompactSerializer::serialize
<std::string
>(obj
);
66 folly::doNotOptimizeAway(s
);
72 template <class Struct
>
73 void add_filled_benchmark() {
74 std::string name
= folly::pretty_name
<Struct
>();
75 name
= name
.substr(name
.rfind("::") + 2) + "_filled";
77 folly::addBenchmark(__FILE__
, name
, [&] {
80 for (int i
= 0; i
< kIterationCount
; i
++) {
81 auto s
= CompactSerializer::serialize
<std::string
>(obj
);
82 folly::doNotOptimizeAway(s
);
88 template <class Struct
>
89 void add_first_element_nonempty_benchmark() {
90 std::string name
= folly::pretty_name
<Struct
>();
91 name
= name
.substr(name
.rfind("::") + 2) + "_first_element_nonempty";
93 folly::addBenchmark(__FILE__
, name
, [&] {
95 fill_first(*obj
.interal());
96 for (int i
= 0; i
< kIterationCount
; i
++) {
97 auto s
= CompactSerializer::serialize
<std::string
>(obj
);
98 folly::doNotOptimizeAway(s
);
104 template <class Struct
>
105 void add_filled_half_benchmark() {
106 std::string name
= folly::pretty_name
<Struct
>();
107 name
= name
.substr(name
.rfind("::") + 2) + "_half_filled";
109 folly::addBenchmark(__FILE__
, name
, [&] {
111 fill_half(*obj
.interal());
112 for (int i
= 0; i
< kIterationCount
; i
++) {
113 auto s
= CompactSerializer::serialize
<std::string
>(obj
);
114 folly::doNotOptimizeAway(s
);
120 template <class Struct
>
121 void add_middle_element_nonempty_benchmark() {
122 std::string name
= folly::pretty_name
<Struct
>();
123 name
= name
.substr(name
.rfind("::") + 2) + "_middle_element_nonempty";
124 folly::addBenchmark(__FILE__
, name
, [&] {
126 fill_middle(*obj
.interal());
127 for (int i
= 0; i
< kIterationCount
; i
++) {
128 auto s
= CompactSerializer::serialize
<std::string
>(obj
);
129 folly::doNotOptimizeAway(s
);
135 template <class Struct
>
136 void add_last_element_nonempty_benchmark() {
137 std::string name
= folly::pretty_name
<Struct
>();
138 name
= name
.substr(name
.rfind("::") + 2) + "_last_element_nonempty";
139 folly::addBenchmark(__FILE__
, name
, [&] {
141 fill_last(*obj
.interal());
142 for (int i
= 0; i
< kIterationCount
; i
++) {
143 auto s
= CompactSerializer::serialize
<std::string
>(obj
);
144 folly::doNotOptimizeAway(s
);
151 template <typename T
>
152 void addTerseWriteBenchmarks() {
153 add_benchmark
<T
>(true);
154 add_filled_half_benchmark
<T
>();
155 add_filled_benchmark
<T
>();
156 add_first_element_nonempty_benchmark
<T
>();
157 add_middle_element_nonempty_benchmark
<T
>();
158 add_last_element_nonempty_benchmark
<T
>();
161 void addBenchmarks() {
162 add_benchmark
<struct_8
>();
163 addTerseWriteBenchmarks
<terse_struct_8
>();
164 add_benchmark
<struct_16
>();
165 addTerseWriteBenchmarks
<terse_struct_16
>();
166 add_benchmark
<struct_32
>();
167 addTerseWriteBenchmarks
<terse_struct_32
>();
168 add_benchmark
<struct_64
>();
169 addTerseWriteBenchmarks
<terse_struct_64
>();
170 add_benchmark
<struct_128
>();
171 addTerseWriteBenchmarks
<terse_struct_128
>();
172 add_benchmark
<struct_256
>();
173 addTerseWriteBenchmarks
<terse_struct_256
>();
174 add_benchmark
<struct_512
>();
175 addTerseWriteBenchmarks
<terse_struct_512
>();
178 } // namespace apache::thrift::test
180 int main(int argc
, char** argv
) {
181 folly::init(&argc
, &argv
);
182 apache::thrift::test::addBenchmarks();
183 folly::runBenchmarks();