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
28const char* c_string_6_characters = "abcdef";
29const char* c_string_60_characters = "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef";
30const 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
132std::string string_6_characters = c_string_6_characters;
133std::string string_60_characters = c_string_60_characters;
134std::string string_6000_characters = c_string_6000_characters;
135
136std::string_view string_view_6_characters = c_string_6_characters;
137std::string_view string_view_60_characters = c_string_60_characters;
138std::string_view string_view_6000_characters = c_string_6000_characters;
139
140static 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
146template <class T>
147static void BM_format(benchmark::State& state, const T& value) {
148 for (auto _ : state)
149 benchmark::DoNotOptimize(std::format("{}", value));
150}
151
152template <class Container, class T>
153static 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
161template <class T, class F>
162static 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
199BENCHMARK_CAPTURE(BM_sprintf, C_string_len_6, c_string_6_characters);
200FORMAT_BENCHMARKS(C_string_len_6, c_string_6_characters)
201FORMAT_BENCHMARKS(string_len_6, string_6_characters)
202FORMAT_BENCHMARKS(string_view_len_6, string_view_6_characters)
203
204BENCHMARK_CAPTURE(BM_sprintf, C_string_len_60, c_string_60_characters);
205FORMAT_BENCHMARKS(C_string_len_60, c_string_60_characters)
206FORMAT_BENCHMARKS(string_len_60, string_60_characters)
207FORMAT_BENCHMARKS(string_view_len_60, string_view_60_characters)
208
209BENCHMARK_CAPTURE(BM_sprintf, C_string_len_6000, c_string_6000_characters);
210FORMAT_BENCHMARKS(C_string_len_6000, c_string_6000_characters)
211FORMAT_BENCHMARKS(string_len_6000, string_6000_characters)
212FORMAT_BENCHMARKS(string_view_len_6000, string_view_6000_characters)
213
214BENCHMARK_MAIN();
215

source code of libcxx/test/benchmarks/format/write_string_comparison.bench.cpp