1 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 2 // See https://llvm.org/LICENSE.txt for license information. 3 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 4 // 5 //===----------------------------------------------------------------------===// 6 7 #ifndef _LIBCPP_HAS_NO_UNICODE 8 9 #include <array> 10 #include <format> 11 12 #include "benchmark/benchmark.h" 13 14 #include "test_macros.h" 15 16 template <class CharT, size_t N> 17 class tester { 18 static constexpr size_t size_ = N - 1; 19 std::array<CharT, 100 * size_> data_; 20 21 public: 22 explicit constexpr tester(const CharT (&input)[N]) { 23 auto it = data_.begin(); 24 for (int i = 0; i < 100; ++i) 25 it = std::copy_n(input, size_, it); 26 } 27 28 constexpr size_t size() const noexcept { return data_.size(); } 29 constexpr const CharT* begin() const noexcept { return data_.begin(); } 30 constexpr const CharT* end() const noexcept { return data_.end(); } 31 32 void test(benchmark::State& state) const { 33 for (auto _ : state) 34 benchmark::DoNotOptimize(std::__format_spec::__get_string_alignment( 35 begin(), end(), 1'000'000, 1'000'000)); 36 state.SetItemsProcessed(state.iterations() * size()); 37 } 38 }; 39 40 #define TEST(u8) \ 41 if constexpr (std::same_as<CharT, char>) { \ 42 constexpr auto p = tester{u8}; \ 43 p.test(state); \ 44 } else if constexpr (std::same_as<CharT, char16_t>) { \ 45 constexpr auto p = tester{TEST_CONCAT(u, u8)}; \ 46 p.test(state); \ 47 } else { \ 48 constexpr auto p = tester{TEST_CONCAT(U, u8)}; \ 49 p.test(state); \ 50 } 51 52 template <class CharT> 53 static void BM_EstimateLengthNoMultiByte(benchmark::State& state) { 54 TEST("The quick brown fox jumps over the lazy dog"); 55 } 56 57 template <class CharT> 58 static void BM_EstimateLengthTwoByteDE(benchmark::State& state) { 59 static_assert(sizeof("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich") == 67); 60 61 // https://en.wikipedia.org/wiki/Pangram 62 TEST("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich"); 63 } 64 65 template <class CharT> 66 static void BM_EstimateLengthTwoBytePL(benchmark::State& state) { 67 static_assert(sizeof("Stróż pchnął kość w quiz gędźb vel fax myjń") == 53); 68 69 // https://en.wikipedia.org/wiki/Pangram 70 TEST("Stróż pchnął kość w quiz gędźb vel fax myjń"); 71 } 72 73 // All values below are 1100, which is is the first multi column sequence. 74 template <class CharT> 75 static void BM_EstimateLengthThreeByteSingleColumnLow(benchmark::State& state) { 76 static_assert(sizeof("\u0800\u0801\u0802\u0803\u0804\u0805\u0806\u0807" 77 "\u0808\u0809\u080a\u080b\u080c\u080d\u080e\u080f") == 78 49); 79 80 TEST("\u0800\u0801\u0802\u0803\u0804\u0805\u0806\u0807" 81 "\u0808\u0809\u080a\u080b\u080c\u080d\u080e\u080f"); 82 } 83 84 template <class CharT> 85 static void 86 BM_EstimateLengthThreeByteSingleColumnHigh(benchmark::State& state) { 87 static_assert(sizeof("\u1800\u1801\u1802\u1803\u1804\u1805\u1806\u1807" 88 "\u1808\u1809\u180a\u180b\u180c\u180d\u180e\u180f") == 89 49); 90 91 TEST("\u1800\u1801\u1802\u1803\u1804\u1805\u1806\u1807" 92 "\u1808\u1809\u180a\u180b\u180c\u180d\u180e\u180f"); 93 } 94 95 template <class CharT> 96 static void BM_EstimateLengthThreeByteDoubleColumn(benchmark::State& state) { 97 static_assert(sizeof("\u1100\u0801\u0802\u0803\u0804\u0805\u0806\u0807" 98 "\u1108\u0809\u080a\u080b\u080c\u080d\u080e\u080f") == 99 49); 100 101 TEST("\u1100\u0801\u0802\u0803\u0804\u0805\u0806\u0807" 102 "\u1108\u0809\u080a\u080b\u080c\u080d\u080e\u080f"); 103 } 104 105 template <class CharT> 106 static void BM_EstimateLengthThreeByte(benchmark::State& state) { 107 static_assert(sizeof("\u1400\u1501\ubbbb\uff00\u0800\u4099\uabcd\u4000" 108 "\u8ead\ubeef\u1111\u4987\u4321\uffff\u357a\ud50e") == 109 49); 110 111 TEST("\u1400\u1501\ubbbb\uff00\u0800\u4099\uabcd\u4000" 112 "\u8ead\ubeef\u1111\u4987\u4321\uffff\u357a\ud50e"); 113 } 114 115 template <class CharT> 116 static void BM_EstimateLengthFourByteSingleColumn(benchmark::State& state) { 117 static_assert(sizeof("\U00010000\U00010001\U00010002\U00010003" 118 "\U00010004\U00010005\U00010006\U00010007" 119 "\U00010008\U00010009\U0001000a\U0001000b" 120 "\U0001000c\U0001000d\U0001000e\U0001000f") == 65); 121 122 TEST("\U00010000\U00010001\U00010002\U00010003" 123 "\U00010004\U00010005\U00010006\U00010007" 124 "\U00010008\U00010009\U0001000a\U0001000b" 125 "\U0001000c\U0001000d\U0001000e\U0001000f"); 126 } 127 128 template <class CharT> 129 static void BM_EstimateLengthFourByteDoubleColumn(benchmark::State& state) { 130 static_assert(sizeof("\U00020000\U00020002\U00020002\U00020003" 131 "\U00020004\U00020005\U00020006\U00020007" 132 "\U00020008\U00020009\U0002000a\U0002000b" 133 "\U0002000c\U0002000d\U0002000e\U0002000f") == 65); 134 135 TEST("\U00020000\U00020002\U00020002\U00020003" 136 "\U00020004\U00020005\U00020006\U00020007" 137 "\U00020008\U00020009\U0002000a\U0002000b" 138 "\U0002000c\U0002000d\U0002000e\U0002000f"); 139 } 140 141 template <class CharT> 142 static void BM_EstimateLengthFourByte(benchmark::State& state) { 143 static_assert(sizeof("\U00010000\U00010001\U00010002\U00010003" 144 "\U00020004\U00020005\U00020006\U00020007" 145 "\U00010008\U00010009\U0001000a\U0001000b" 146 "\U0002000c\U0002000d\U0002000e\U0002000f") == 65); 147 148 TEST("\U00010000\U00010001\U00010002\U00010003" 149 "\U00020004\U00020005\U00020006\U00020007" 150 "\U00010008\U00010009\U0001000a\U0001000b" 151 "\U0002000c\U0002000d\U0002000e\U0002000f"); 152 } 153 154 BENCHMARK_TEMPLATE(BM_EstimateLengthNoMultiByte, char); 155 BENCHMARK_TEMPLATE(BM_EstimateLengthTwoByteDE, char); 156 BENCHMARK_TEMPLATE(BM_EstimateLengthTwoBytePL, char); 157 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnLow, char); 158 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnHigh, char); 159 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteDoubleColumn, char); 160 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByte, char); 161 BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteSingleColumn, char); 162 BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteDoubleColumn, char); 163 BENCHMARK_TEMPLATE(BM_EstimateLengthFourByte, char); 164 165 BENCHMARK_TEMPLATE(BM_EstimateLengthNoMultiByte, char16_t); 166 BENCHMARK_TEMPLATE(BM_EstimateLengthTwoByteDE, char16_t); 167 BENCHMARK_TEMPLATE(BM_EstimateLengthTwoBytePL, char16_t); 168 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnLow, char16_t); 169 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnHigh, char16_t); 170 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteDoubleColumn, char16_t); 171 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByte, char16_t); 172 BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteSingleColumn, char16_t); 173 BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteDoubleColumn, char16_t); 174 BENCHMARK_TEMPLATE(BM_EstimateLengthFourByte, char16_t); 175 176 BENCHMARK_TEMPLATE(BM_EstimateLengthNoMultiByte, char32_t); 177 BENCHMARK_TEMPLATE(BM_EstimateLengthTwoByteDE, char32_t); 178 BENCHMARK_TEMPLATE(BM_EstimateLengthTwoBytePL, char32_t); 179 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnLow, char32_t); 180 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnHigh, char32_t); 181 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteDoubleColumn, char32_t); 182 BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByte, char32_t); 183 BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteSingleColumn, char32_t); 184 BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteDoubleColumn, char32_t); 185 BENCHMARK_TEMPLATE(BM_EstimateLengthFourByte, char32_t); 186 187 int main(int argc, char** argv) { 188 benchmark::Initialize(&argc, argv); 189 if (benchmark::ReportUnrecognizedArguments(argc, argv)) 190 return 1; 191 192 benchmark::RunSpecifiedBenchmarks(); 193 } 194 #else 195 int main(int, char**) { return 0; } 196 #endif 197