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 <algorithm> |
11 | #include <array> |
12 | #include <iterator> |
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> |
26 | static void BM_format_to_n_string_back_inserter(benchmark::State& state) { |
27 | using CharT = typename Container::value_type; |
28 | size_t size = state.range(pos: 0); |
29 | auto str = std::basic_string<CharT>(2 * size, CharT('*')); |
30 | |
31 | for (auto _ : state) { |
32 | Container output; |
33 | benchmark::DoNotOptimize(std::format_to_n(std::back_inserter(output), size, CSTR("{}" ), str)); |
34 | } |
35 | state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); |
36 | } |
37 | |
38 | /*** Begin ***/ |
39 | |
40 | template <class Container> |
41 | static void BM_format_to_n_string_begin(benchmark::State& state) { |
42 | using CharT = typename Container::value_type; |
43 | size_t size = state.range(pos: 0); |
44 | auto str = std::basic_string<CharT>(2 * size, CharT('*')); |
45 | |
46 | Container output(size, CharT('-')); |
47 | for (auto _ : state) |
48 | benchmark::DoNotOptimize(std::format_to_n(std::begin(output), size, CSTR("{}" ), str)); |
49 | |
50 | state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); |
51 | } |
52 | |
53 | /*** Pointer ***/ |
54 | |
55 | template <class CharT> |
56 | static void BM_format_to_n_string_span(benchmark::State& state) { |
57 | size_t size = state.range(pos: 0); |
58 | auto str = std::basic_string<CharT>(2 * 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_n(std::begin(output), size, CSTR("{}" ), str)); |
64 | |
65 | state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); |
66 | } |
67 | |
68 | template <class CharT> |
69 | static void BM_format_to_n_string_pointer(benchmark::State& state) { |
70 | size_t size = state.range(pos: 0); |
71 | auto str = std::basic_string<CharT>(2 * 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_n(output, size, CSTR("{}" ), str)); |
77 | |
78 | state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); |
79 | } |
80 | |
81 | /*** Main ***/ |
82 | |
83 | BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::string)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
84 | BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::vector<char>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
85 | BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::list<char>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
86 | BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::string)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
87 | BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::vector<char>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
88 | BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::list<char>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
89 | BENCHMARK_TEMPLATE(BM_format_to_n_string_span, char)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
90 | BENCHMARK_TEMPLATE(BM_format_to_n_string_pointer, char)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
91 | |
92 | BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::wstring)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
93 | BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::vector<wchar_t>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
94 | BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::list<wchar_t>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
95 | BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::wstring)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
96 | BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::vector<wchar_t>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
97 | BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::list<wchar_t>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
98 | BENCHMARK_TEMPLATE(BM_format_to_n_string_span, wchar_t)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
99 | BENCHMARK_TEMPLATE(BM_format_to_n_string_pointer, wchar_t)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20); |
100 | |
101 | int main(int argc, char** argv) { |
102 | benchmark::Initialize(argc: &argc, argv); |
103 | if (benchmark::ReportUnrecognizedArguments(argc, argv)) |
104 | return 1; |
105 | |
106 | benchmark::RunSpecifiedBenchmarks(); |
107 | } |
108 | |