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 <charconv>
16#include <cstdio>
17#include <format>
18#include <iterator>
19#include <list>
20#include <random>
21#include <vector>
22
23#include "benchmark/benchmark.h"
24
25std::array data = [] {
26 std::uniform_int_distribution<int> distribution{std::numeric_limits<int>::min(), std::numeric_limits<int>::max()};
27 std::mt19937 generator;
28 std::array<int, 1000> result;
29 std::generate_n(first: result.begin(), n: result.size(), gen: [&] { return distribution(generator); });
30 return result;
31}();
32
33static void BM_sprintf(benchmark::State& state) {
34 std::array<char, 100> output;
35 while (state.KeepRunningBatch(n: data.size()))
36 for (auto value : data) {
37 std::sprintf(s: output.data(), format: "%d", value);
38 benchmark::DoNotOptimize(value: output.data());
39 }
40}
41
42static void BM_to_string(benchmark::State& state) {
43 while (state.KeepRunningBatch(n: data.size()))
44 for (auto value : data) {
45 std::string s = std::to_string(val: value);
46 benchmark::DoNotOptimize(value&: s);
47 }
48}
49
50static void BM_to_chars(benchmark::State& state) {
51 std::array<char, 100> output;
52
53 while (state.KeepRunningBatch(n: data.size()))
54 for (auto value : data) {
55 std::to_chars(first: output.data(), last: output.data() + output.size(), value: value);
56 benchmark::DoNotOptimize(value: output.data());
57 }
58}
59
60static void BM_to_chars_as_string(benchmark::State& state) {
61 std::array<char, 100> output;
62
63 while (state.KeepRunningBatch(n: data.size()))
64 for (auto value : data) {
65 char* end = std::to_chars(first: output.data(), last: output.data() + output.size(), value: value).ptr;
66 std::string s{output.data(), end};
67 benchmark::DoNotOptimize(value&: s);
68 }
69}
70
71static void BM_format(benchmark::State& state) {
72 while (state.KeepRunningBatch(n: data.size()))
73 for (auto value : data) {
74 std::string s = std::format("{}", value);
75 benchmark::DoNotOptimize(value&: s);
76 }
77}
78
79template <class C>
80static void BM_format_to_back_inserter(benchmark::State& state) {
81 while (state.KeepRunningBatch(n: data.size()))
82 for (auto value : data) {
83 C c;
84 std::format_to(std::back_inserter(c), "{}", value);
85 benchmark::DoNotOptimize(c);
86 }
87}
88
89template <class F>
90static void BM_format_to_iterator(benchmark::State& state, F&& f) {
91 auto output = f();
92 while (state.KeepRunningBatch(n: data.size()))
93 for (auto value : data) {
94 std::format_to(std::begin(output), "{}", value);
95 benchmark::DoNotOptimize(std::begin(output));
96 }
97}
98
99BENCHMARK(BM_sprintf);
100BENCHMARK(BM_to_string);
101BENCHMARK(BM_to_chars);
102BENCHMARK(BM_to_chars_as_string);
103BENCHMARK(BM_format);
104BENCHMARK_TEMPLATE(BM_format_to_back_inserter, std::string);
105BENCHMARK_TEMPLATE(BM_format_to_back_inserter, std::vector<char>);
106BENCHMARK_TEMPLATE(BM_format_to_back_inserter, std::list<char>);
107BENCHMARK_CAPTURE(BM_format_to_iterator, <std::array>, ([] {
108 std::array<char, 100> a;
109 return a;
110 }));
111BENCHMARK_CAPTURE(BM_format_to_iterator, <std::string>, ([] {
112 std::string s;
113 s.resize(100);
114 return s;
115 }));
116BENCHMARK_CAPTURE(BM_format_to_iterator, <std::vector>, ([] {
117 std::vector<char> v;
118 v.resize(100);
119 return v;
120 }));
121
122BENCHMARK_MAIN();
123

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