2 * Copyright 2017 Facebook, Inc.
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 <folly/Format.h>
19 #include <glog/logging.h>
21 #include <folly/Benchmark.h>
22 #include <folly/FBVector.h>
23 #include <folly/dynamic.h>
24 #include <folly/init/Init.h>
25 #include <folly/json.h>
27 using namespace folly;
31 std::array<char, 300> bigBuf;
35 BENCHMARK(octal_snprintf, iters) {
38 bigBuf.data(), bigBuf.size(), "%o", static_cast<unsigned int>(iters));
42 BENCHMARK_RELATIVE(octal_uintToOctal, iters) {
46 detail::kMaxOctalLength,
47 static_cast<unsigned int>(iters));
53 BENCHMARK(hex_snprintf, iters) {
56 bigBuf.data(), bigBuf.size(), "%x", static_cast<unsigned int>(iters));
60 BENCHMARK_RELATIVE(hex_uintToHex, iters) {
62 detail::uintToHexLower(
63 bigBuf.data(), detail::kMaxHexLength, static_cast<unsigned int>(iters));
69 BENCHMARK(intAppend_snprintf) {
71 for (int i = -1000; i < 1000; i++) {
72 snprintf(bigBuf.data(), bigBuf.size(), "%d", i);
73 out.append(bigBuf.data());
77 BENCHMARK_RELATIVE(intAppend_to) {
79 for (int i = -1000; i < 1000; i++) {
84 BENCHMARK_RELATIVE(intAppend_format) {
86 for (int i = -1000; i < 1000; i++) {
87 format(&out, "{}", i);
93 template <size_t... Indexes>
94 int snprintf20Numbers(int i, std::index_sequence<Indexes...>) {
95 static_assert(20 == sizeof...(Indexes), "Must have exactly 20 indexes");
103 (i + static_cast<int>(Indexes))...);
106 BENCHMARK(bigFormat_snprintf, iters) {
108 for (int i = -100; i < 100; i++) {
109 snprintf20Numbers(i, std::make_index_sequence<20>());
114 template <size_t... Indexes>
115 decltype(auto) format20Numbers(int i, std::index_sequence<Indexes...>) {
116 static_assert(20 == sizeof...(Indexes), "Must have exactly 20 indexes");
122 (i + static_cast<int>(Indexes))...);
125 BENCHMARK_RELATIVE(bigFormat_format, iters) {
126 BenchmarkSuspender suspender;
128 auto writeToBuf = [&p](StringPiece sp) mutable {
129 memcpy(p, sp.data(), sp.size());
134 for (int i = -100; i < 100; i++) {
136 suspender.dismissing([&] {
137 format20Numbers(i, std::make_index_sequence<20>())(writeToBuf);
143 BENCHMARK_DRAW_LINE()
145 BENCHMARK(format_nested_strings, iters) {
146 BenchmarkSuspender suspender;
148 for (int i = 0; i < 1000; ++i) {
150 suspender.dismissing([&]() {
154 format("{} {}", i, i + 1).str(),
155 format("{} {}", -i, -i - 1).str());
161 BENCHMARK_RELATIVE(format_nested_fbstrings, iters) {
162 BenchmarkSuspender suspender;
164 for (int i = 0; i < 1000; ++i) {
166 suspender.dismissing([&] {
170 format("{} {}", i, i + 1).fbstr(),
171 format("{} {}", -i, -i - 1).fbstr());
177 BENCHMARK_RELATIVE(format_nested_direct, iters) {
178 BenchmarkSuspender suspender;
180 for (int i = 0; i < 1000; ++i) {
182 suspender.dismissing([&] {
186 format("{} {}", i, i + 1),
187 format("{} {}", -i, -i - 1));
193 // Benchmark results on my dev server (20-core Intel Xeon E5-2660 v2 @ 2.20GHz)
195 // ============================================================================
196 // folly/test/FormatBenchmark.cpp relative time/iter iters/s
197 // ============================================================================
198 // octal_snprintf 79.30ns 12.61M
199 // octal_uintToOctal 3452.19% 2.30ns 435.35M
200 // ----------------------------------------------------------------------------
201 // hex_snprintf 73.59ns 13.59M
202 // hex_uintToHex 4507.53% 1.63ns 612.49M
203 // ----------------------------------------------------------------------------
204 // intAppend_snprintf 191.50us 5.22K
205 // intAppend_to 552.46% 34.66us 28.85K
206 // intAppend_format 215.76% 88.76us 11.27K
207 // ----------------------------------------------------------------------------
208 // bigFormat_snprintf 178.03us 5.62K
209 // bigFormat_format 90.41% 196.91us 5.08K
210 // ----------------------------------------------------------------------------
211 // format_nested_strings 317.65us 3.15K
212 // format_nested_fbstrings 99.89% 318.01us 3.14K
213 // format_nested_direct 116.52% 272.62us 3.67K
214 // ============================================================================
216 int main(int argc, char* argv[]) {
217 init(&argc, &argv, true);