1 | #include "benchmark/benchmark.h" |
2 | #include "test_macros.h" |
3 | |
4 | #include <mutex> |
5 | #include <sstream> |
6 | |
7 | TEST_NOINLINE double istream_numbers(); |
8 | |
9 | double istream_numbers(std::locale* loc) { |
10 | const char* a[] = {"-6 69 -71 2.4882e-02 -100 101 -2.00005 5000000 -50000000" , |
11 | "-25 71 7 -9.3262e+01 -100 101 -2.00005 5000000 -50000000" , |
12 | "-14 53 46 -6.7026e-02 -100 101 -2.00005 5000000 -50000000" }; |
13 | |
14 | int a1, a2, a3, a4, a5, a6, a7; |
15 | double f1 = 0.0, f2 = 0.0, q = 0.0; |
16 | for (int i = 0; i < 3; i++) { |
17 | std::istringstream s(a[i]); |
18 | if (loc) |
19 | s.imbue(loc: *loc); |
20 | s >> a1 >> a2 >> a3 >> f1 >> a4 >> a5 >> f2 >> a6 >> a7; |
21 | q += (a1 + a2 + a3 + a4 + a5 + a6 + a7 + f1 + f2) / 1000000; |
22 | } |
23 | return q; |
24 | } |
25 | |
26 | struct LocaleSelector { |
27 | std::locale* imbue; |
28 | std::locale old; |
29 | static std::mutex mutex; |
30 | |
31 | LocaleSelector(benchmark::State& state) { |
32 | std::lock_guard guard(mutex); |
33 | switch (state.range(pos: 0)) { |
34 | case 0: { |
35 | old = std::locale::global(loc: std::locale::classic()); |
36 | imbue = nullptr; |
37 | break; |
38 | } |
39 | case 1: { |
40 | old = std::locale::global(loc: std::locale::classic()); |
41 | thread_local std::locale loc("en_US.UTF-8" ); |
42 | imbue = &loc; |
43 | break; |
44 | } |
45 | case 2: { |
46 | old = std::locale::global(loc: std::locale::classic()); |
47 | static std::locale loc("en_US.UTF-8" ); |
48 | imbue = &loc; |
49 | break; |
50 | } |
51 | case 3: { |
52 | old = std::locale::global(loc: std::locale("en_US.UTF-8" )); |
53 | imbue = nullptr; |
54 | break; |
55 | } |
56 | } |
57 | } |
58 | |
59 | ~LocaleSelector() { |
60 | std::lock_guard guard(mutex); |
61 | std::locale::global(loc: old); |
62 | } |
63 | }; |
64 | |
65 | std::mutex LocaleSelector::mutex; |
66 | |
67 | static void BM_Istream_numbers(benchmark::State& state) { |
68 | LocaleSelector sel(state); |
69 | double i = 0; |
70 | while (state.KeepRunning()) |
71 | benchmark::DoNotOptimize(value&: i += istream_numbers(loc: sel.imbue)); |
72 | } |
73 | BENCHMARK(BM_Istream_numbers)->DenseRange(start: 0, limit: 3)->UseRealTime()->Threads(t: 1)->ThreadPerCpu(); |
74 | |
75 | static void BM_Ostream_number(benchmark::State& state) { |
76 | LocaleSelector sel(state); |
77 | while (state.KeepRunning()) { |
78 | std::ostringstream ss; |
79 | if (sel.imbue) |
80 | ss.imbue(loc: *sel.imbue); |
81 | ss << 0; |
82 | benchmark::DoNotOptimize(value: ss.str().c_str()); |
83 | } |
84 | } |
85 | BENCHMARK(BM_Ostream_number)->DenseRange(start: 0, limit: 3)->UseRealTime()->Threads(t: 1)->ThreadPerCpu(); |
86 | |
87 | BENCHMARK_MAIN(); |
88 | |