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 |
10 | |
11 | #include "benchmark/benchmark.h" |
12 | #include <bitset> |
13 | #include <cmath> |
14 | #include <cstddef> |
15 | #include <random> |
16 | |
17 | template <std::size_t N> |
18 | struct GenerateBitset { |
19 | // Construct a bitset with N bits, where each bit is set with probability p. |
20 | static std::bitset<N> generate(double p) { |
21 | std::bitset<N> b; |
22 | if (p <= 0.0) |
23 | return b; |
24 | if (p >= 1.0) |
25 | return ~b; |
26 | |
27 | std::random_device rd; |
28 | std::mt19937 gen(rd()); |
29 | std::bernoulli_distribution d(p); |
30 | for (std::size_t i = 0; i < N; ++i) |
31 | b[i] = d(gen); |
32 | |
33 | return b; |
34 | } |
35 | |
36 | static std::bitset<N> sparse() { return generate(p: 0.1); } |
37 | static std::bitset<N> dense() { return generate(p: 0.9); } |
38 | static std::bitset<N> uniform() { return generate(p: 0.5); } |
39 | }; |
40 | |
41 | template <std::size_t N> |
42 | static void BM_BitsetToString(benchmark::State& state) { |
43 | double p = state.range(0) / 100.0; |
44 | std::bitset<N> b = GenerateBitset<N>::generate(p); |
45 | benchmark::DoNotOptimize(b); |
46 | |
47 | for (auto _ : state) { |
48 | benchmark::DoNotOptimize(b.to_string()); |
49 | } |
50 | } |
51 | |
52 | // Sparse bitset |
53 | BENCHMARK(BM_BitsetToString<32>)->Arg(10)->Name("BM_BitsetToString<32>/Sparse (10%)" ); |
54 | BENCHMARK(BM_BitsetToString<64>)->Arg(10)->Name("BM_BitsetToString<64>/Sparse (10%)" ); |
55 | BENCHMARK(BM_BitsetToString<128>)->Arg(10)->Name("BM_BitsetToString<128>/Sparse (10%)" ); |
56 | BENCHMARK(BM_BitsetToString<256>)->Arg(10)->Name("BM_BitsetToString<256>/Sparse (10%)" ); |
57 | BENCHMARK(BM_BitsetToString<512>)->Arg(10)->Name("BM_BitsetToString<512>/Sparse (10%)" ); |
58 | BENCHMARK(BM_BitsetToString<1024>)->Arg(10)->Name("BM_BitsetToString<1024>/Sparse (10%)" ); |
59 | BENCHMARK(BM_BitsetToString<2048>)->Arg(10)->Name("BM_BitsetToString<2048>/Sparse (10%)" ); |
60 | BENCHMARK(BM_BitsetToString<4096>)->Arg(10)->Name("BM_BitsetToString<4096>/Sparse (10%)" ); |
61 | BENCHMARK(BM_BitsetToString<8192>)->Arg(10)->Name("BM_BitsetToString<8192>/Sparse (10%)" ); |
62 | BENCHMARK(BM_BitsetToString<16384>)->Arg(10)->Name("BM_BitsetToString<16384>/Sparse (10%)" ); |
63 | BENCHMARK(BM_BitsetToString<32768>)->Arg(10)->Name("BM_BitsetToString<32768>/Sparse (10%)" ); |
64 | BENCHMARK(BM_BitsetToString<65536>)->Arg(10)->Name("BM_BitsetToString<65536>/Sparse (10%)" ); |
65 | BENCHMARK(BM_BitsetToString<131072>)->Arg(10)->Name("BM_BitsetToString<131072>/Sparse (10%)" ); |
66 | BENCHMARK(BM_BitsetToString<262144>)->Arg(10)->Name("BM_BitsetToString<262144>/Sparse (10%)" ); |
67 | BENCHMARK(BM_BitsetToString<524288>)->Arg(10)->Name("BM_BitsetToString<524288>/Sparse (10%)" ); |
68 | BENCHMARK(BM_BitsetToString<1048576>)->Arg(10)->Name("BM_BitsetToString<1048576>/Sparse (10%)" ); // 1 << 20 |
69 | |
70 | // Dense bitset |
71 | BENCHMARK(BM_BitsetToString<32>)->Arg(90)->Name("BM_BitsetToString<32>/Dense (90%)" ); |
72 | BENCHMARK(BM_BitsetToString<64>)->Arg(90)->Name("BM_BitsetToString<64>/Dense (90%)" ); |
73 | BENCHMARK(BM_BitsetToString<128>)->Arg(90)->Name("BM_BitsetToString<128>/Dense (90%)" ); |
74 | BENCHMARK(BM_BitsetToString<256>)->Arg(90)->Name("BM_BitsetToString<256>/Dense (90%)" ); |
75 | BENCHMARK(BM_BitsetToString<512>)->Arg(90)->Name("BM_BitsetToString<512>/Dense (90%)" ); |
76 | BENCHMARK(BM_BitsetToString<1024>)->Arg(90)->Name("BM_BitsetToString<1024>/Dense (90%)" ); |
77 | BENCHMARK(BM_BitsetToString<2048>)->Arg(90)->Name("BM_BitsetToString<2048>/Dense (90%)" ); |
78 | BENCHMARK(BM_BitsetToString<4096>)->Arg(90)->Name("BM_BitsetToString<4096>/Dense (90%)" ); |
79 | BENCHMARK(BM_BitsetToString<8192>)->Arg(90)->Name("BM_BitsetToString<8192>/Dense (90%)" ); |
80 | BENCHMARK(BM_BitsetToString<16384>)->Arg(90)->Name("BM_BitsetToString<16384>/Dense (90%)" ); |
81 | BENCHMARK(BM_BitsetToString<32768>)->Arg(90)->Name("BM_BitsetToString<32768>/Dense (90%)" ); |
82 | BENCHMARK(BM_BitsetToString<65536>)->Arg(90)->Name("BM_BitsetToString<65536>/Dense (90%)" ); |
83 | BENCHMARK(BM_BitsetToString<131072>)->Arg(90)->Name("BM_BitsetToString<131072>/Dense (90%)" ); |
84 | BENCHMARK(BM_BitsetToString<262144>)->Arg(90)->Name("BM_BitsetToString<262144>/Dense (90%)" ); |
85 | BENCHMARK(BM_BitsetToString<524288>)->Arg(90)->Name("BM_BitsetToString<524288>/Dense (90%)" ); |
86 | BENCHMARK(BM_BitsetToString<1048576>)->Arg(90)->Name("BM_BitsetToString<1048576>/Dense (90%)" ); // 1 << 20 |
87 | |
88 | // Uniform bitset |
89 | BENCHMARK(BM_BitsetToString<32>)->Arg(50)->Name("BM_BitsetToString<32>/Uniform (50%)" ); |
90 | BENCHMARK(BM_BitsetToString<64>)->Arg(50)->Name("BM_BitsetToString<64>/Uniform (50%)" ); |
91 | BENCHMARK(BM_BitsetToString<128>)->Arg(50)->Name("BM_BitsetToString<128>/Uniform (50%)" ); |
92 | BENCHMARK(BM_BitsetToString<256>)->Arg(50)->Name("BM_BitsetToString<256>/Uniform (50%)" ); |
93 | BENCHMARK(BM_BitsetToString<512>)->Arg(50)->Name("BM_BitsetToString<512>/Uniform (50%)" ); |
94 | BENCHMARK(BM_BitsetToString<1024>)->Arg(50)->Name("BM_BitsetToString<1024>/Uniform (50%)" ); |
95 | BENCHMARK(BM_BitsetToString<2048>)->Arg(50)->Name("BM_BitsetToString<2048>/Uniform (50%)" ); |
96 | BENCHMARK(BM_BitsetToString<4096>)->Arg(50)->Name("BM_BitsetToString<4096>/Uniform (50%)" ); |
97 | BENCHMARK(BM_BitsetToString<8192>)->Arg(50)->Name("BM_BitsetToString<8192>/Uniform (50%)" ); |
98 | BENCHMARK(BM_BitsetToString<16384>)->Arg(50)->Name("BM_BitsetToString<16384>/Uniform (50%)" ); |
99 | BENCHMARK(BM_BitsetToString<32768>)->Arg(50)->Name("BM_BitsetToString<32768>/Uniform (50%)" ); |
100 | BENCHMARK(BM_BitsetToString<65536>)->Arg(50)->Name("BM_BitsetToString<65536>/Uniform (50%)" ); |
101 | BENCHMARK(BM_BitsetToString<131072>)->Arg(50)->Name("BM_BitsetToString<131072>/Uniform (50%)" ); |
102 | BENCHMARK(BM_BitsetToString<262144>)->Arg(50)->Name("BM_BitsetToString<262144>/Uniform (50%)" ); |
103 | BENCHMARK(BM_BitsetToString<524288>)->Arg(50)->Name("BM_BitsetToString<524288>/Uniform (50%)" ); |
104 | BENCHMARK(BM_BitsetToString<1048576>)->Arg(50)->Name("BM_BitsetToString<1048576>/Uniform (50%)" ); // 1 << 20 |
105 | |
106 | static void BM_ctor_ull(benchmark::State& state) { |
107 | unsigned long long val = (1ULL << state.range(0)) - 1; |
108 | for (auto _ : state) { |
109 | std::bitset<128> b(val); |
110 | benchmark::DoNotOptimize(b); |
111 | } |
112 | } |
113 | |
114 | BENCHMARK(BM_ctor_ull)->DenseRange(1, 63); |
115 | |
116 | BENCHMARK_MAIN(); |
117 | |