086dd880412a8409a58ce66593681b300fe9a408
[folly.git] / folly / test / FormatBenchmark.cpp
1 /*
2  * Copyright 2013 Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "folly/Format.h"
18
19 #include <glog/logging.h>
20
21 #include "folly/FBVector.h"
22 #include "folly/Benchmark.h"
23 #include "folly/dynamic.h"
24 #include "folly/json.h"
25
26 using namespace folly;
27
28 namespace {
29
30 char bigBuf[300];
31
32 }  // namespace
33
34 BENCHMARK(octal_sprintf, iters) {
35   while (iters--) {
36     sprintf(bigBuf, "%o", static_cast<unsigned int>(iters));
37   }
38 }
39
40 BENCHMARK_RELATIVE(octal_uintToOctal, iters) {
41   while (iters--) {
42     detail::uintToOctal(bigBuf, detail::kMaxOctalLength,
43                         static_cast<unsigned int>(iters));
44   }
45 }
46
47 BENCHMARK_DRAW_LINE()
48
49 BENCHMARK(hex_sprintf, iters) {
50   while (iters--) {
51     sprintf(bigBuf, "%x", static_cast<unsigned int>(iters));
52   }
53 }
54
55 BENCHMARK_RELATIVE(hex_uintToHex, iters) {
56   while (iters--) {
57     detail::uintToHexLower(bigBuf, detail::kMaxHexLength,
58                            static_cast<unsigned int>(iters));
59   }
60 }
61
62 BENCHMARK_DRAW_LINE()
63
64 BENCHMARK(intAppend_sprintf) {
65   fbstring out;
66   for (int i = -1000; i < 1000; i++) {
67     sprintf(bigBuf, "%d", i);
68     out.append(bigBuf);
69   }
70 }
71
72 BENCHMARK_RELATIVE(intAppend_to) {
73   fbstring out;
74   for (int i = -1000; i < 1000; i++) {
75     toAppend(i, &out);
76   }
77 }
78
79 BENCHMARK_RELATIVE(intAppend_format) {
80   fbstring out;
81   for (int i = -1000; i < 1000; i++) {
82     format(&out, "{}", i);
83   }
84 }
85
86 BENCHMARK_DRAW_LINE()
87
88 BENCHMARK(bigFormat_sprintf, iters) {
89   while (iters--) {
90     for (int i = -100; i < 100; i++) {
91       sprintf(bigBuf,
92               "%d %d %d %d %d"
93               "%d %d %d %d %d"
94               "%d %d %d %d %d"
95               "%d %d %d %d %d",
96               i, i+1, i+2, i+3, i+4,
97               i+5, i+6, i+7, i+8, i+9,
98               i+10, i+11, i+12, i+13, i+14,
99               i+15, i+16, i+17, i+18, i+19);
100     }
101   }
102 }
103
104 BENCHMARK_RELATIVE(bigFormat_format, iters) {
105   char* p;
106   auto writeToBuf = [&p] (StringPiece sp) mutable {
107     memcpy(p, sp.data(), sp.size());
108     p += sp.size();
109   };
110
111   while (iters--) {
112     for (int i = -100; i < 100; i++) {
113       p = bigBuf;
114       format("{} {} {} {} {}"
115              "{} {} {} {} {}"
116              "{} {} {} {} {}"
117              "{} {} {} {} {}",
118               i, i+1, i+2, i+3, i+4,
119               i+5, i+6, i+7, i+8, i+9,
120               i+10, i+11, i+12, i+13, i+14,
121               i+15, i+16, i+17, i+18, i+19)(writeToBuf);
122     }
123   }
124 }
125
126 BENCHMARK_DRAW_LINE()
127
128 BENCHMARK(format_nested_strings, iters) {
129   while (iters--) {
130     fbstring out;
131     for (int i = 0; i < 1000; ++i) {
132       out.clear();
133       format(&out, "{} {}",
134              format("{} {}", i, i + 1).str(),
135              format("{} {}", -i, -i - 1).str());
136     }
137   }
138 }
139
140 BENCHMARK_RELATIVE(format_nested_fbstrings, iters) {
141   while (iters--) {
142     fbstring out;
143     for (int i = 0; i < 1000; ++i) {
144       out.clear();
145       format(&out, "{} {}",
146              format("{} {}", i, i + 1).fbstr(),
147              format("{} {}", -i, -i - 1).fbstr());
148     }
149   }
150 }
151
152 BENCHMARK_RELATIVE(format_nested_direct, iters) {
153   while (iters--) {
154     fbstring out;
155     for (int i = 0; i < 1000; ++i) {
156       out.clear();
157       format(&out, "{} {}",
158              format("{} {}", i, i + 1),
159              format("{} {}", -i, -i - 1));
160     }
161   }
162 }
163
164 // Benchmark results on my dev server (dual-CPU Xeon L5520 @ 2.7GHz)
165 //
166 // ============================================================================
167 // folly/test/FormatTest.cpp                         relative  ns/iter  iters/s
168 // ============================================================================
169 // octal_sprintf                                               100.57     9.94M
170 // octal_uintToOctal                                 2599.47%    3.87   258.46M
171 // ----------------------------------------------------------------------------
172 // hex_sprintf                                                 100.13     9.99M
173 // hex_uintToHex                                     3331.75%    3.01   332.73M
174 // ----------------------------------------------------------------------------
175 // intAppend_sprintf                                           406.07K    2.46K
176 // intAppend_to                                       166.03%  244.58K    4.09K
177 // intAppend_format                                   147.57%  275.17K    3.63K
178 // ----------------------------------------------------------------------------
179 // bigFormat_sprintf                                           255.40K    3.92K
180 // bigFormat_format                                   102.18%  249.94K    4.00K
181 // ============================================================================
182
183 int main(int argc, char *argv[]) {
184   google::ParseCommandLineFlags(&argc, &argv, true);
185   runBenchmarks();
186   return 0;
187 }