From c72b52a352357a375cfaedc7acb6b1db709a9a00 Mon Sep 17 00:00:00 2001 From: Phil Willoughby Date: Thu, 19 Jan 2017 13:42:48 -0800 Subject: [PATCH] Modernise and clang-format existing formatting benchmark Summary: Changes nothing fundamental, just makes it easier to work on in the future. Reviewed By: yfeldblum Differential Revision: D4435805 fbshipit-source-id: 725944a12922abde137bb7e21726c97beb558b5f --- folly/test/FormatBenchmark.cpp | 157 ++++++++++++++++++++------------- 1 file changed, 95 insertions(+), 62 deletions(-) diff --git a/folly/test/FormatBenchmark.cpp b/folly/test/FormatBenchmark.cpp index f93faac3..05162dfc 100644 --- a/folly/test/FormatBenchmark.cpp +++ b/folly/test/FormatBenchmark.cpp @@ -18,54 +18,59 @@ #include -#include #include +#include #include +#include #include using namespace folly; namespace { -char bigBuf[300]; +std::array bigBuf; -} // namespace +} // namespace -BENCHMARK(octal_sprintf, iters) { +BENCHMARK(octal_snprintf, iters) { while (iters--) { - sprintf(bigBuf, "%o", static_cast(iters)); + snprintf( + bigBuf.data(), bigBuf.size(), "%o", static_cast(iters)); } } BENCHMARK_RELATIVE(octal_uintToOctal, iters) { while (iters--) { - detail::uintToOctal(bigBuf, detail::kMaxOctalLength, - static_cast(iters)); + detail::uintToOctal( + bigBuf.data(), + detail::kMaxOctalLength, + static_cast(iters)); } } BENCHMARK_DRAW_LINE() -BENCHMARK(hex_sprintf, iters) { +BENCHMARK(hex_snprintf, iters) { while (iters--) { - sprintf(bigBuf, "%x", static_cast(iters)); + snprintf( + bigBuf.data(), bigBuf.size(), "%x", static_cast(iters)); } } BENCHMARK_RELATIVE(hex_uintToHex, iters) { while (iters--) { - detail::uintToHexLower(bigBuf, detail::kMaxHexLength, - static_cast(iters)); + detail::uintToHexLower( + bigBuf.data(), detail::kMaxHexLength, static_cast(iters)); } } BENCHMARK_DRAW_LINE() -BENCHMARK(intAppend_sprintf) { +BENCHMARK(intAppend_snprintf) { fbstring out; for (int i = -1000; i < 1000; i++) { - sprintf(bigBuf, "%d", i); - out.append(bigBuf); + snprintf(bigBuf.data(), bigBuf.size(), "%d", i); + out.append(bigBuf.data()); } } @@ -85,40 +90,52 @@ BENCHMARK_RELATIVE(intAppend_format) { BENCHMARK_DRAW_LINE() -BENCHMARK(bigFormat_sprintf, iters) { +template +int snprintf20Numbers(int i, std::index_sequence) { + static_assert(20 == sizeof...(Indexes), "Must have exactly 20 indexes"); + return snprintf( + bigBuf.data(), + bigBuf.size(), + "%d %d %d %d %d" + "%d %d %d %d %d" + "%d %d %d %d %d" + "%d %d %d %d %d", + (i + static_cast(Indexes))...); +} + +BENCHMARK(bigFormat_snprintf, iters) { while (iters--) { for (int i = -100; i < 100; i++) { - sprintf(bigBuf, - "%d %d %d %d %d" - "%d %d %d %d %d" - "%d %d %d %d %d" - "%d %d %d %d %d", - i, i+1, i+2, i+3, i+4, - i+5, i+6, i+7, i+8, i+9, - i+10, i+11, i+12, i+13, i+14, - i+15, i+16, i+17, i+18, i+19); + snprintf20Numbers(i, std::make_index_sequence<20>()); } } } +template +decltype(auto) format20Numbers(int i, std::index_sequence) { + static_assert(20 == sizeof...(Indexes), "Must have exactly 20 indexes"); + return format( + "{} {} {} {} {}" + "{} {} {} {} {}" + "{} {} {} {} {}" + "{} {} {} {} {}", + (i + static_cast(Indexes))...); +} + BENCHMARK_RELATIVE(bigFormat_format, iters) { + BenchmarkSuspender suspender; char* p; - auto writeToBuf = [&p] (StringPiece sp) mutable { + auto writeToBuf = [&p](StringPiece sp) mutable { memcpy(p, sp.data(), sp.size()); p += sp.size(); }; while (iters--) { for (int i = -100; i < 100; i++) { - p = bigBuf; - format("{} {} {} {} {}" - "{} {} {} {} {}" - "{} {} {} {} {}" - "{} {} {} {} {}", - i, i+1, i+2, i+3, i+4, - i+5, i+6, i+7, i+8, i+9, - i+10, i+11, i+12, i+13, i+14, - i+15, i+16, i+17, i+18, i+19)(writeToBuf); + p = bigBuf.data(); + suspender.dismissing([&] { + format20Numbers(i, std::make_index_sequence<20>())(writeToBuf); + }); } } } @@ -126,62 +143,78 @@ BENCHMARK_RELATIVE(bigFormat_format, iters) { BENCHMARK_DRAW_LINE() BENCHMARK(format_nested_strings, iters) { + BenchmarkSuspender suspender; while (iters--) { - fbstring out; for (int i = 0; i < 1000; ++i) { - out.clear(); - format(&out, "{} {}", - format("{} {}", i, i + 1).str(), - format("{} {}", -i, -i - 1).str()); + fbstring out; + suspender.dismissing([&]() { + format( + &out, + "{} {}", + format("{} {}", i, i + 1).str(), + format("{} {}", -i, -i - 1).str()); + }); } } } BENCHMARK_RELATIVE(format_nested_fbstrings, iters) { + BenchmarkSuspender suspender; while (iters--) { - fbstring out; for (int i = 0; i < 1000; ++i) { - out.clear(); - format(&out, "{} {}", - format("{} {}", i, i + 1).fbstr(), - format("{} {}", -i, -i - 1).fbstr()); + fbstring out; + suspender.dismissing([&] { + format( + &out, + "{} {}", + format("{} {}", i, i + 1).fbstr(), + format("{} {}", -i, -i - 1).fbstr()); + }); } } } BENCHMARK_RELATIVE(format_nested_direct, iters) { + BenchmarkSuspender suspender; while (iters--) { - fbstring out; for (int i = 0; i < 1000; ++i) { - out.clear(); - format(&out, "{} {}", - format("{} {}", i, i + 1), - format("{} {}", -i, -i - 1)); + fbstring out; + suspender.dismissing([&] { + format( + &out, + "{} {}", + format("{} {}", i, i + 1), + format("{} {}", -i, -i - 1)); + }); } } } -// Benchmark results on my dev server (dual-CPU Xeon L5520 @ 2.7GHz) +// Benchmark results on my dev server (20-core Intel Xeon E5-2660 v2 @ 2.20GHz) // // ============================================================================ -// folly/test/FormatTest.cpp relative ns/iter iters/s +// folly/test/FormatBenchmark.cpp relative time/iter iters/s // ============================================================================ -// octal_sprintf 100.57 9.94M -// octal_uintToOctal 2599.47% 3.87 258.46M +// octal_snprintf 79.30ns 12.61M +// octal_uintToOctal 3452.19% 2.30ns 435.35M +// ---------------------------------------------------------------------------- +// hex_snprintf 73.59ns 13.59M +// hex_uintToHex 4507.53% 1.63ns 612.49M // ---------------------------------------------------------------------------- -// hex_sprintf 100.13 9.99M -// hex_uintToHex 3331.75% 3.01 332.73M +// intAppend_snprintf 191.50us 5.22K +// intAppend_to 552.46% 34.66us 28.85K +// intAppend_format 215.76% 88.76us 11.27K // ---------------------------------------------------------------------------- -// intAppend_sprintf 406.07K 2.46K -// intAppend_to 166.03% 244.58K 4.09K -// intAppend_format 147.57% 275.17K 3.63K +// bigFormat_snprintf 178.03us 5.62K +// bigFormat_format 90.41% 196.91us 5.08K // ---------------------------------------------------------------------------- -// bigFormat_sprintf 255.40K 3.92K -// bigFormat_format 102.18% 249.94K 4.00K +// format_nested_strings 317.65us 3.15K +// format_nested_fbstrings 99.89% 318.01us 3.14K +// format_nested_direct 116.52% 272.62us 3.67K // ============================================================================ -int main(int argc, char *argv[]) { - gflags::ParseCommandLineFlags(&argc, &argv, true); +int main(int argc, char* argv[]) { + init(&argc, &argv, true); runBenchmarks(); return 0; } -- 2.34.1