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> 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> 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> 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> 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 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