1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <wctype.h>
18
19 #include <numeric>
20 #include <random>
21 #include <vector>
22
23 #include <benchmark/benchmark.h>
24 #include "util.h"
25
RandomAscii()26 static std::vector<wint_t> RandomAscii() {
27 std::vector<wint_t> result(128);
28 std::iota(result.begin(), result.end(), 0);
29 std::shuffle(result.begin(), result.end(), std::mt19937{std::random_device{}()});
30 return result;
31 }
32
RandomNonAscii()33 static std::vector<wint_t> RandomNonAscii() {
34 std::vector<wint_t> result;
35 std::mt19937 rng{std::random_device{}()};
36 std::uniform_int_distribution<> d(0x80, 0xffff);
37 for (size_t i = 0; i < 128; i++) result.push_back(d(rng));
38 return result;
39 }
40
41 #define WCTYPE_BENCHMARK(__benchmark, fn, random_fn) \
42 static void __benchmark##_##fn(benchmark::State& state) { \
43 auto chars = random_fn(); \
44 for (auto _ : state) { \
45 for (char ch : chars) { \
46 benchmark::DoNotOptimize(fn(ch)); \
47 } \
48 } \
49 state.SetBytesProcessed(state.iterations() * chars.size()); \
50 } \
51 BIONIC_BENCHMARK(__benchmark##_##fn)
52
53 #define WCTYPE_BENCHMARK_ASCII(__benchmark, fn) WCTYPE_BENCHMARK(__benchmark, fn, RandomAscii)
54
55 #define WCTYPE_BENCHMARK_NON_ASCII(__benchmark, fn) \
56 WCTYPE_BENCHMARK(__benchmark, fn, RandomNonAscii)
57
58 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswalnum);
59 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswalpha);
60 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswblank);
61 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswcntrl);
62 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswdigit);
63 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswgraph);
64 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswlower);
65 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswprint);
66 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswpunct);
67 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswspace);
68 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswupper);
69 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii, iswxdigit);
70
71 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii_transform, towlower);
72 WCTYPE_BENCHMARK_ASCII(BM_wctype_ascii_transform, towupper);
73
74 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswalnum);
75 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswalpha);
76 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswblank);
77 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswcntrl);
78 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswdigit);
79 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswgraph);
80 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswlower);
81 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswprint);
82 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswpunct);
83 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswspace);
84 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswupper);
85 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii, iswxdigit);
86
87 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii_transform, towlower);
88 WCTYPE_BENCHMARK_NON_ASCII(BM_wctype_non_ascii_transform, towupper);
89