From 161b4811d5382627e09c0538cf84d9c109688fc5 Mon Sep 17 00:00:00 2001 From: Mark de Wever Date: Sat, 30 Mar 2024 17:35:56 +0100 Subject: [PATCH] [libc++][format][1/7] Adds more benchmarks. This patch is the start of a series to improve the speed of std::format, std::format_to, std::format_to_n, and std::formatted_size. This is mostly achieved by changing the __output_buffer class. This new __output_buffer class also makes it easier to implement buffering for P3107R5 "Permit an efficient implementation of std::print" --- libcxx/test/benchmarks/CMakeLists.txt | 3 + libcxx/test/benchmarks/format.bench.cpp | 6 +- .../format/write_double_comparison.bench.cpp | 117 ++++++++++ .../format/write_int_comparison.bench.cpp | 117 ++++++++++ .../format/write_string_comparison.bench.cpp | 221 ++++++++++++++++++ 5 files changed, 462 insertions(+), 2 deletions(-) create mode 100644 libcxx/test/benchmarks/format/write_double_comparison.bench.cpp create mode 100644 libcxx/test/benchmarks/format/write_int_comparison.bench.cpp create mode 100644 libcxx/test/benchmarks/format/write_string_comparison.bench.cpp diff --git a/libcxx/test/benchmarks/CMakeLists.txt b/libcxx/test/benchmarks/CMakeLists.txt index 616cf0ff8d237..b402af8d80dae 100644 --- a/libcxx/test/benchmarks/CMakeLists.txt +++ b/libcxx/test/benchmarks/CMakeLists.txt @@ -147,6 +147,9 @@ set(BENCHMARK_TESTS deque_iterator.bench.cpp exception_ptr.bench.cpp filesystem.bench.cpp + format/write_double_comparison.bench.cpp + format/write_int_comparison.bench.cpp + format/write_string_comparison.bench.cpp format_to_n.bench.cpp format_to.bench.cpp format.bench.cpp diff --git a/libcxx/test/benchmarks/format.bench.cpp b/libcxx/test/benchmarks/format.bench.cpp index 17eaccb18ee1c..22f369f0d3be0 100644 --- a/libcxx/test/benchmarks/format.bench.cpp +++ b/libcxx/test/benchmarks/format.bench.cpp @@ -20,8 +20,10 @@ static void BM_format_string(benchmark::State& state) { size_t size = state.range(0); std::basic_string str(size, CharT('*')); - while (state.KeepRunningBatch(str.size())) - benchmark::DoNotOptimize(std::format(CSTR("{}"), str)); + while (state.KeepRunningBatch(str.size())) { + std::basic_string s = std::format(CSTR("{}"), str); + benchmark::DoNotOptimize(s); + } state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); } diff --git a/libcxx/test/benchmarks/format/write_double_comparison.bench.cpp b/libcxx/test/benchmarks/format/write_double_comparison.bench.cpp new file mode 100644 index 0000000000000..93db5f1f5f456 --- /dev/null +++ b/libcxx/test/benchmarks/format/write_double_comparison.bench.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "benchmark/benchmark.h" + +std::array data = [] { + std::uniform_real_distribution distribution; + std::mt19937 generator; + std::array result; + std::generate_n(result.begin(), result.size(), [&] { return distribution(generator); }); + return result; +}(); + +static void BM_sprintf(benchmark::State& state) { + std::array output; + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + sprintf(output.data(), "%f", value); + benchmark::DoNotOptimize(output.data()); + } +} + +static void BM_to_string(benchmark::State& state) { + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + std::string s = std::to_string(value); + benchmark::DoNotOptimize(s); + } +} + +static void BM_to_chars(benchmark::State& state) { + std::array output; + + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + std::to_chars(output.data(), output.data() + output.size(), value); + benchmark::DoNotOptimize(output.data()); + } +} + +static void BM_to_chars_as_string(benchmark::State& state) { + std::array output; + + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + char* end = std::to_chars(output.data(), output.data() + output.size(), value).ptr; + std::string s{output.data(), end}; + benchmark::DoNotOptimize(s); + } +} + +static void BM_format(benchmark::State& state) { + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + std::string s = std::format("{}", value); + benchmark::DoNotOptimize(s); + } +} + +template +static void BM_format_to_back_inserter(benchmark::State& state) { + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + C c; + std::format_to(std::back_inserter(c), "{}", value); + benchmark::DoNotOptimize(c); + } +} + +template +static void BM_format_to_iterator(benchmark::State& state, F&& f) { + auto output = f(); + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + std::format_to(std::begin(output), "{}", value); + benchmark::DoNotOptimize(std::begin(output)); + } +} + +BENCHMARK(BM_sprintf); +BENCHMARK(BM_to_string); +BENCHMARK(BM_to_chars); +BENCHMARK(BM_to_chars_as_string); +BENCHMARK(BM_format); +BENCHMARK_TEMPLATE(BM_format_to_back_inserter, std::string); +BENCHMARK_TEMPLATE(BM_format_to_back_inserter, std::vector); +BENCHMARK_TEMPLATE(BM_format_to_back_inserter, std::list); +BENCHMARK_CAPTURE(BM_format_to_iterator, , ([] { + std::array a; + return a; + })); +BENCHMARK_CAPTURE(BM_format_to_iterator, , ([] { + std::string s; + s.resize(100); + return s; + })); +BENCHMARK_CAPTURE(BM_format_to_iterator, , ([] { + std::vector v; + v.resize(100); + return v; + })); + +BENCHMARK_MAIN(); diff --git a/libcxx/test/benchmarks/format/write_int_comparison.bench.cpp b/libcxx/test/benchmarks/format/write_int_comparison.bench.cpp new file mode 100644 index 0000000000000..835a56f036225 --- /dev/null +++ b/libcxx/test/benchmarks/format/write_int_comparison.bench.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "benchmark/benchmark.h" + +std::array data = [] { + std::uniform_int_distribution distribution{std::numeric_limits::min(), std::numeric_limits::max()}; + std::mt19937 generator; + std::array result; + std::generate_n(result.begin(), result.size(), [&] { return distribution(generator); }); + return result; +}(); + +static void BM_sprintf(benchmark::State& state) { + std::array output; + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + sprintf(output.data(), "%d", value); + benchmark::DoNotOptimize(output.data()); + } +} + +static void BM_to_string(benchmark::State& state) { + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + std::string s = std::to_string(value); + benchmark::DoNotOptimize(s); + } +} + +static void BM_to_chars(benchmark::State& state) { + std::array output; + + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + std::to_chars(output.data(), output.data() + output.size(), value); + benchmark::DoNotOptimize(output.data()); + } +} + +static void BM_to_chars_as_string(benchmark::State& state) { + std::array output; + + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + char* end = std::to_chars(output.data(), output.data() + output.size(), value).ptr; + std::string s{output.data(), end}; + benchmark::DoNotOptimize(s); + } +} + +static void BM_format(benchmark::State& state) { + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + std::string s = std::format("{}", value); + benchmark::DoNotOptimize(s); + } +} + +template +static void BM_format_to_back_inserter(benchmark::State& state) { + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + C c; + std::format_to(std::back_inserter(c), "{}", value); + benchmark::DoNotOptimize(c); + } +} + +template +static void BM_format_to_iterator(benchmark::State& state, F&& f) { + auto output = f(); + while (state.KeepRunningBatch(data.size())) + for (auto value : data) { + std::format_to(std::begin(output), "{}", value); + benchmark::DoNotOptimize(std::begin(output)); + } +} + +BENCHMARK(BM_sprintf); +BENCHMARK(BM_to_string); +BENCHMARK(BM_to_chars); +BENCHMARK(BM_to_chars_as_string); +BENCHMARK(BM_format); +BENCHMARK_TEMPLATE(BM_format_to_back_inserter, std::string); +BENCHMARK_TEMPLATE(BM_format_to_back_inserter, std::vector); +BENCHMARK_TEMPLATE(BM_format_to_back_inserter, std::list); +BENCHMARK_CAPTURE(BM_format_to_iterator, , ([] { + std::array a; + return a; + })); +BENCHMARK_CAPTURE(BM_format_to_iterator, , ([] { + std::string s; + s.resize(100); + return s; + })); +BENCHMARK_CAPTURE(BM_format_to_iterator, , ([] { + std::vector v; + v.resize(100); + return v; + })); + +BENCHMARK_MAIN(); diff --git a/libcxx/test/benchmarks/format/write_string_comparison.bench.cpp b/libcxx/test/benchmarks/format/write_string_comparison.bench.cpp new file mode 100644 index 0000000000000..bbd49f785d60d --- /dev/null +++ b/libcxx/test/benchmarks/format/write_string_comparison.bench.cpp @@ -0,0 +1,221 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "benchmark/benchmark.h" +#include "test_macros.h" + +const char* c_string_6_characters = "abcdef"; +const char* c_string_60_characters = "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef"; +const char* c_string_6000_characters = + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" + "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef"; // 100 lines + +std::string string_6_characters = c_string_6_characters; +std::string string_60_characters = c_string_60_characters; +std::string string_6000_characters = c_string_6000_characters; + +std::string_view string_view_6_characters = c_string_6_characters; +std::string_view string_view_60_characters = c_string_60_characters; +std::string_view string_view_6000_characters = c_string_6000_characters; + +static void BM_sprintf(benchmark::State& state, const char* value) { + std::array output; + for (auto _ : state) + benchmark::DoNotOptimize(sprintf(output.data(), "%s", value)); +} + +template +static void BM_format(benchmark::State& state, const T& value) { + for (auto _ : state) + benchmark::DoNotOptimize(std::format("{}", value)); +} + +template +static void BM_format_to_back_inserter(benchmark::State& state, const T& value) { + for (auto _ : state) { + Container c; + std::format_to(std::back_inserter(c), "{}", value); + benchmark::DoNotOptimize(c); + } +} + +template +static void BM_format_to_iterator(benchmark::State& state, const T& value, F&& f) { + auto output = f(); + for (auto _ : state) { + benchmark::DoNotOptimize(std::format_to(std::begin(output), "{}", value)); + } +} + +#define FORMAT_BENCHMARKS(name, variable) \ + BENCHMARK_CAPTURE(BM_format, name, variable); \ + \ + BENCHMARK_TEMPLATE1_CAPTURE(BM_format_to_back_inserter, std::string, name, variable); \ + BENCHMARK_TEMPLATE1_CAPTURE(BM_format_to_back_inserter, std::vector, name, variable); \ + BENCHMARK_TEMPLATE1_CAPTURE(BM_format_to_back_inserter, std::deque, name, variable); \ + BENCHMARK_TEMPLATE1_CAPTURE(BM_format_to_back_inserter, std::list, name, variable); \ + \ + BENCHMARK_CAPTURE(BM_format_to_iterator, name, variable, ([] { \ + std::array a; \ + return a; \ + })); \ + BENCHMARK_CAPTURE(BM_format_to_iterator, name, variable, ([] { \ + std::string s; \ + s.resize(10'000); \ + return s; \ + })); \ + BENCHMARK_CAPTURE(BM_format_to_iterator, name, variable, ([] { \ + std::vector v; \ + v.resize(10'000); \ + return v; \ + })); \ + BENCHMARK_CAPTURE(BM_format_to_iterator, name, variable, ([] { \ + std::deque d; \ + d.resize(10'000); \ + return d; \ + })); \ + \ + /* */ + +// Verify these types have an iterator that format has optimizations for. +LIBCPP_STATIC_ASSERT(std::same_as::iterator, char*> || // the type depends on an ABI flag + std::same_as::iterator, std::__wrap_iter>); +LIBCPP_STATIC_ASSERT(std::same_as>); +LIBCPP_STATIC_ASSERT(std::same_as::iterator, std::__wrap_iter>); + +// Verify these types have an iterator that format does not optimize for +LIBCPP_STATIC_ASSERT(!std::same_as::iterator, char*> && + !std::same_as::iterator, std::__wrap_iter>); +LIBCPP_STATIC_ASSERT(!std::same_as::iterator, char*> && + !std::same_as::iterator, std::__wrap_iter>); + +BENCHMARK_CAPTURE(BM_sprintf, C_string_len_6, c_string_6_characters); +FORMAT_BENCHMARKS(C_string_len_6, c_string_6_characters) +FORMAT_BENCHMARKS(string_len_6, string_6_characters) +FORMAT_BENCHMARKS(string_view_len_6, string_view_6_characters) + +BENCHMARK_CAPTURE(BM_sprintf, C_string_len_60, c_string_60_characters); +FORMAT_BENCHMARKS(C_string_len_60, c_string_60_characters) +FORMAT_BENCHMARKS(string_len_60, string_60_characters) +FORMAT_BENCHMARKS(string_view_len_60, string_view_60_characters) + +BENCHMARK_CAPTURE(BM_sprintf, C_string_len_6000, c_string_6000_characters); +FORMAT_BENCHMARKS(C_string_len_6000, c_string_6000_characters) +FORMAT_BENCHMARKS(string_len_6000, string_6000_characters) +FORMAT_BENCHMARKS(string_view_len_6000, string_view_6000_characters) + +BENCHMARK_MAIN();