1 //===----------------------------------------------------------------------===//
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7 
8 #include <format>
9 
10 #include <iterator>
11 #include <algorithm>
12 #include <array>
13 #include <list>
14 #include <span>
15 #include <string>
16 #include <vector>
17 
18 #include "benchmark/benchmark.h"
19 #include "make_string.h"
20 
21 #define CSTR(S) MAKE_CSTRING(CharT, S)
22 
23 /*** Back inserter ***/
24 
25 template <class Container>
BM_format_to_string_back_inserter(benchmark::State & state)26 static void BM_format_to_string_back_inserter(benchmark::State& state) {
27   using CharT = typename Container::value_type;
28   size_t size = state.range(0);
29   auto str = std::basic_string<CharT>(size, CharT('*'));
30 
31   for (auto _ : state) {
32     Container output;
33     benchmark::DoNotOptimize(std::format_to(std::back_inserter(output), CSTR("{}"), str));
34   }
35   state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
36 }
37 
38 /*** Begin ***/
39 
40 template <class Container>
BM_format_to_string_begin(benchmark::State & state)41 static void BM_format_to_string_begin(benchmark::State& state) {
42   using CharT = typename Container::value_type;
43   size_t size = state.range(0);
44   auto str = std::basic_string<CharT>(size, CharT('*'));
45 
46   Container output(size, CharT('-'));
47   for (auto _ : state)
48     benchmark::DoNotOptimize(std::format_to(std::begin(output), CSTR("{}"), str));
49 
50   state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
51 }
52 
53 /*** Pointer ***/
54 
55 template <class CharT>
BM_format_to_string_span(benchmark::State & state)56 static void BM_format_to_string_span(benchmark::State& state) {
57   size_t size = state.range(0);
58   auto str = std::basic_string<CharT>(size, CharT('*'));
59 
60   auto buffer = std::basic_string<CharT>(size, CharT('-'));
61   std::span<CharT> output{buffer};
62   for (auto _ : state)
63     benchmark::DoNotOptimize(std::format_to(std::begin(output), CSTR("{}"), str));
64 
65   state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
66 }
67 
68 template <class CharT>
BM_format_to_string_pointer(benchmark::State & state)69 static void BM_format_to_string_pointer(benchmark::State& state) {
70   size_t size = state.range(0);
71   auto str = std::basic_string<CharT>(size, CharT('*'));
72 
73   auto buffer = std::basic_string<CharT>(size, CharT('-'));
74   CharT* output = buffer.data();
75   for (auto _ : state)
76     benchmark::DoNotOptimize(std::format_to(output, CSTR("{}"), str));
77 
78   state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
79 }
80 
81 /*** Main ***/
82 
83 BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::string)->RangeMultiplier(2)->Range(1, 1 << 20);
84 BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::vector<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
85 BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::list<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
86 BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::string)->RangeMultiplier(2)->Range(1, 1 << 20);
87 BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::vector<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
88 BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::list<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
89 BENCHMARK_TEMPLATE(BM_format_to_string_span, char)->RangeMultiplier(2)->Range(1, 1 << 20);
90 BENCHMARK_TEMPLATE(BM_format_to_string_pointer, char)->RangeMultiplier(2)->Range(1, 1 << 20);
91 
92 BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20);
93 BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::vector<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
94 BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::list<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
95 BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20);
96 BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::vector<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
97 BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::list<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
98 BENCHMARK_TEMPLATE(BM_format_to_string_span, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20);
99 BENCHMARK_TEMPLATE(BM_format_to_string_pointer, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20);
100 
main(int argc,char ** argv)101 int main(int argc, char** argv) {
102   benchmark::Initialize(&argc, argv);
103   if (benchmark::ReportUnrecognizedArguments(argc, argv))
104     return 1;
105 
106   benchmark::RunSpecifiedBenchmarks();
107 }
108