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#include <format>
12
13#include <algorithm>
14#include <array>
15#include <iterator>
16#include <list>
17#include <span>
18#include <string>
19#include <vector>
20
21#include "benchmark/benchmark.h"
22#include "make_string.h"
23#include "test_macros.h"
24
25#define CSTR(S) MAKE_CSTRING(CharT, S)
26
27/*** Back inserter ***/
28
29template <class Container>
30static void BM_format_to_n_string_back_inserter(benchmark::State& state) {
31 using CharT = typename Container::value_type;
32 size_t size = state.range(pos: 0);
33 auto str = std::basic_string<CharT>(2 * size, CharT('*'));
34
35 for (auto _ : state) {
36 Container output;
37 benchmark::DoNotOptimize(std::format_to_n(std::back_inserter(output), size, CSTR("{}"), str));
38 }
39 state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
40}
41
42/*** Begin ***/
43
44template <class Container>
45static void BM_format_to_n_string_begin(benchmark::State& state) {
46 using CharT = typename Container::value_type;
47 size_t size = state.range(pos: 0);
48 auto str = std::basic_string<CharT>(2 * size, CharT('*'));
49
50 Container output(size, CharT('-'));
51 for (auto _ : state)
52 benchmark::DoNotOptimize(std::format_to_n(std::begin(output), size, CSTR("{}"), str));
53
54 state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
55}
56
57/*** Pointer ***/
58
59template <class CharT>
60static void BM_format_to_n_string_span(benchmark::State& state) {
61 size_t size = state.range(pos: 0);
62 auto str = std::basic_string<CharT>(2 * size, CharT('*'));
63
64 auto buffer = std::basic_string<CharT>(size, CharT('-'));
65 std::span<CharT> output{buffer};
66 for (auto _ : state)
67 benchmark::DoNotOptimize(std::format_to_n(std::begin(output), size, CSTR("{}"), str));
68
69 state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
70}
71
72template <class CharT>
73static void BM_format_to_n_string_pointer(benchmark::State& state) {
74 size_t size = state.range(pos: 0);
75 auto str = std::basic_string<CharT>(2 * size, CharT('*'));
76
77 auto buffer = std::basic_string<CharT>(size, CharT('-'));
78 CharT* output = buffer.data();
79 for (auto _ : state)
80 benchmark::DoNotOptimize(std::format_to_n(output, size, CSTR("{}"), str));
81
82 state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
83}
84
85/*** Main ***/
86
87BENCHMARK(BM_format_to_n_string_back_inserter<std::string>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
88BENCHMARK(BM_format_to_n_string_back_inserter<std::vector<char>>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
89BENCHMARK(BM_format_to_n_string_back_inserter<std::list<char>>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
90BENCHMARK(BM_format_to_n_string_begin<std::string>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
91BENCHMARK(BM_format_to_n_string_begin<std::vector<char>>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
92BENCHMARK(BM_format_to_n_string_begin<std::list<char>>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
93BENCHMARK(BM_format_to_n_string_span<char>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
94BENCHMARK(BM_format_to_n_string_pointer<char>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
95
96#ifndef TEST_HAS_NO_WIDE_CHARACTERS
97BENCHMARK(BM_format_to_n_string_back_inserter<std::wstring>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
98BENCHMARK(BM_format_to_n_string_back_inserter<std::vector<wchar_t>>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
99BENCHMARK(BM_format_to_n_string_back_inserter<std::list<wchar_t>>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
100BENCHMARK(BM_format_to_n_string_begin<std::wstring>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
101BENCHMARK(BM_format_to_n_string_begin<std::vector<wchar_t>>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
102BENCHMARK(BM_format_to_n_string_begin<std::list<wchar_t>>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
103BENCHMARK(BM_format_to_n_string_span<wchar_t>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
104BENCHMARK(BM_format_to_n_string_pointer<wchar_t>)->RangeMultiplier(multiplier: 2)->Range(start: 1, limit: 1 << 20);
105#endif
106
107BENCHMARK_MAIN();
108

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