1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // UNSUPPORTED: c++03, c++11, c++14, c++17 |
10 | |
11 | // Don't warn about std::sprintf |
12 | // ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated |
13 | |
14 | #include <array> |
15 | #include <concepts> |
16 | #include <cstdio> |
17 | #include <deque> |
18 | #include <format> |
19 | #include <iterator> |
20 | #include <list> |
21 | #include <string> |
22 | #include <string_view> |
23 | #include <vector> |
24 | |
25 | #include "benchmark/benchmark.h" |
26 | #include "test_macros.h" |
27 | |
28 | const char* c_string_6_characters = "abcdef" ; |
29 | const char* c_string_60_characters = "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" ; |
30 | const char* c_string_6000_characters = |
31 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
32 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
33 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
34 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
35 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
36 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
37 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
38 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
39 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
40 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
41 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
42 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
43 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
44 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
45 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
46 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
47 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
48 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
49 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
50 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
51 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
52 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
53 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
54 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
55 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
56 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
57 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
58 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
59 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
60 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
61 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
62 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
63 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
64 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
65 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
66 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
67 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
68 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
69 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
70 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
71 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
72 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
73 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
74 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
75 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
76 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
77 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
78 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
79 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
80 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
81 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
82 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
83 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
84 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
85 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
86 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
87 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
88 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
89 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
90 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
91 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
92 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
93 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
94 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
95 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
96 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
97 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
98 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
99 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
100 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
101 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
102 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
103 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
104 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
105 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
106 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
107 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
108 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
109 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
110 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
111 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
112 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
113 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
114 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
115 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
116 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
117 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
118 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
119 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
120 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
121 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
122 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
123 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
124 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
125 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
126 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
127 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
128 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
129 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" |
130 | "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef" ; // 100 lines |
131 | |
132 | std::string string_6_characters = c_string_6_characters; |
133 | std::string string_60_characters = c_string_60_characters; |
134 | std::string string_6000_characters = c_string_6000_characters; |
135 | |
136 | std::string_view string_view_6_characters = c_string_6_characters; |
137 | std::string_view string_view_60_characters = c_string_60_characters; |
138 | std::string_view string_view_6000_characters = c_string_6000_characters; |
139 | |
140 | static void BM_sprintf(benchmark::State& state, const char* value) { |
141 | std::array<char, 10'000> output; |
142 | for (auto _ : state) |
143 | benchmark::DoNotOptimize(value: std::sprintf(s: output.data(), format: "%s" , value)); |
144 | } |
145 | |
146 | template <class T> |
147 | static void BM_format(benchmark::State& state, const T& value) { |
148 | for (auto _ : state) |
149 | benchmark::DoNotOptimize(std::format("{}" , value)); |
150 | } |
151 | |
152 | template <class Container, class T> |
153 | static void BM_format_to_back_inserter(benchmark::State& state, const T& value) { |
154 | for (auto _ : state) { |
155 | Container c; |
156 | std::format_to(std::back_inserter(c), "{}" , value); |
157 | benchmark::DoNotOptimize(c); |
158 | } |
159 | } |
160 | |
161 | template <class T, class F> |
162 | static void BM_format_to_iterator(benchmark::State& state, const T& value, F&& f) { |
163 | auto output = f(); |
164 | for (auto _ : state) { |
165 | benchmark::DoNotOptimize(std::format_to(std::begin(output), "{}" , value)); |
166 | } |
167 | } |
168 | |
169 | #define FORMAT_BENCHMARKS(name, variable) \ |
170 | BENCHMARK_CAPTURE(BM_format, name, variable); \ |
171 | \ |
172 | BENCHMARK_TEMPLATE1_CAPTURE(BM_format_to_back_inserter, std::string, name, variable); \ |
173 | BENCHMARK_TEMPLATE1_CAPTURE(BM_format_to_back_inserter, std::vector<char>, name, variable); \ |
174 | BENCHMARK_TEMPLATE1_CAPTURE(BM_format_to_back_inserter, std::deque<char>, name, variable); \ |
175 | BENCHMARK_TEMPLATE1_CAPTURE(BM_format_to_back_inserter, std::list<char>, name, variable); \ |
176 | \ |
177 | BENCHMARK_CAPTURE(BM_format_to_iterator, <std::array> name, variable, ([] { \ |
178 | std::array<char, 10'000> a; \ |
179 | return a; \ |
180 | })); \ |
181 | BENCHMARK_CAPTURE(BM_format_to_iterator, <std::string> name, variable, ([] { \ |
182 | std::string s; \ |
183 | s.resize(10'000); \ |
184 | return s; \ |
185 | })); \ |
186 | BENCHMARK_CAPTURE(BM_format_to_iterator, <std::vector> name, variable, ([] { \ |
187 | std::vector<char> v; \ |
188 | v.resize(10'000); \ |
189 | return v; \ |
190 | })); \ |
191 | BENCHMARK_CAPTURE(BM_format_to_iterator, <std::deque> name, variable, ([] { \ |
192 | std::deque<char> d; \ |
193 | d.resize(10'000); \ |
194 | return d; \ |
195 | })); \ |
196 | \ |
197 | /* */ |
198 | |
199 | BENCHMARK_CAPTURE(BM_sprintf, C_string_len_6, c_string_6_characters); |
200 | FORMAT_BENCHMARKS(C_string_len_6, c_string_6_characters) |
201 | FORMAT_BENCHMARKS(string_len_6, string_6_characters) |
202 | FORMAT_BENCHMARKS(string_view_len_6, string_view_6_characters) |
203 | |
204 | BENCHMARK_CAPTURE(BM_sprintf, C_string_len_60, c_string_60_characters); |
205 | FORMAT_BENCHMARKS(C_string_len_60, c_string_60_characters) |
206 | FORMAT_BENCHMARKS(string_len_60, string_60_characters) |
207 | FORMAT_BENCHMARKS(string_view_len_60, string_view_60_characters) |
208 | |
209 | BENCHMARK_CAPTURE(BM_sprintf, C_string_len_6000, c_string_6000_characters); |
210 | FORMAT_BENCHMARKS(C_string_len_6000, c_string_6000_characters) |
211 | FORMAT_BENCHMARKS(string_len_6000, string_6000_characters) |
212 | FORMAT_BENCHMARKS(string_view_len_6000, string_view_6000_characters) |
213 | |
214 | BENCHMARK_MAIN(); |
215 | |