Terse Write Benchmark
[hiphop-php.git] / third-party / thrift / src / thrift / test / benchmarks / terse_write_benchmark.cpp
blob84e716e14c65093527c072a4f5ac9f871b706bf9
1 /*
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.
17 #include <string>
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 {
27 namespace {
29 constexpr int kIterationCount = 1'000'000;
31 template <typename T>
32 void fill(T& obj) {
33 op::for_each_field_id<T>([&obj](auto id) { op::get<>(id, obj) = 1; });
35 template <typename T>
36 void fill_half(T& obj) {
37 bool pass = false;
38 op::for_each_field_id<T>([&obj, &pass](auto id) {
39 if (pass = !pass, pass) {
40 op::get<>(id, obj) = 1;
42 });
44 template <typename T>
45 void fill_first(T& obj) {
46 op::get<>(field_id<1>{}, obj) = 1;
48 template <typename T>
49 void fill_middle(T& obj) {
50 op::get<>(field_id<op::size_v<T> / 2 + 1>{}, obj) = 1;
52 template <typename T>
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, [&] {
63 static Struct obj;
64 for (int i = 0; i < kIterationCount; i++) {
65 auto s = CompactSerializer::serialize<std::string>(obj);
66 folly::doNotOptimizeAway(s);
68 return 1;
69 });
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, [&] {
78 static Struct obj;
79 fill(*obj.interal());
80 for (int i = 0; i < kIterationCount; i++) {
81 auto s = CompactSerializer::serialize<std::string>(obj);
82 folly::doNotOptimizeAway(s);
84 return 1;
85 });
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, [&] {
94 static Struct obj;
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);
100 return 1;
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, [&] {
110 static Struct obj;
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);
116 return 1;
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, [&] {
125 static Struct obj;
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);
131 return 1;
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, [&] {
140 static Struct obj;
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);
146 return 1;
149 } // namespace
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();
184 return 0;