22
22
int main (int argc, char ** argv) {
23
23
auto std_rotate = [](auto first, auto middle, auto last) { return std::rotate (first, middle, last); };
24
24
25
- // {std,ranges}::rotate(normal container)
25
+ // Benchmark {std,ranges}::rotate where we rotate various fractions of the range. It is possible to
26
+ // special-case some of these fractions to cleverly perform swap_ranges.
27
+ {
28
+ auto bm = []<class Container >(std::string name, auto rotate, double fraction) {
29
+ benchmark::RegisterBenchmark (
30
+ name,
31
+ [=](auto & st) {
32
+ std::size_t const size = st.range (0 );
33
+ using ValueType = typename Container::value_type;
34
+ Container c;
35
+ std::generate_n (std::back_inserter (c), size, [] { return Generate<ValueType>::random (); });
36
+
37
+ auto nth = std::next (c.begin (), static_cast <std::size_t >(size * fraction));
38
+ for ([[maybe_unused]] auto _ : st) {
39
+ benchmark::DoNotOptimize (c);
40
+ auto result = rotate (c.begin (), nth, c.end ());
41
+ benchmark::DoNotOptimize (result);
42
+ }
43
+ })
44
+ ->Arg (32 )
45
+ ->Arg (1024 )
46
+ ->Arg (8192 );
47
+ };
48
+ bm.operator ()<std::vector<int >>(" std::rotate(vector<int>) (by 1/4)" , std_rotate, 0.25 );
49
+ bm.operator ()<std::deque<int >>(" std::rotate(deque<int>) (by 1/4)" , std_rotate, 0.25 );
50
+ bm.operator ()<std::list<int >>(" std::rotate(list<int>) (by 1/4)" , std_rotate, 0.25 );
51
+ bm.operator ()<std::vector<int >>(" rng::rotate(vector<int>) (by 1/4)" , std::ranges::rotate, 0.25 );
52
+ bm.operator ()<std::deque<int >>(" rng::rotate(deque<int>) (by 1/4)" , std::ranges::rotate, 0.25 );
53
+ bm.operator ()<std::list<int >>(" rng::rotate(list<int>) (by 1/4)" , std::ranges::rotate, 0.25 );
54
+
55
+ bm.operator ()<std::vector<int >>(" std::rotate(vector<int>) (by 1/3)" , std_rotate, 0.33 );
56
+ bm.operator ()<std::deque<int >>(" std::rotate(deque<int>) (by 1/3)" , std_rotate, 0.33 );
57
+ bm.operator ()<std::list<int >>(" std::rotate(list<int>) (by 1/3)" , std_rotate, 0.33 );
58
+ bm.operator ()<std::vector<int >>(" rng::rotate(vector<int>) (by 1/3)" , std::ranges::rotate, 0.33 );
59
+ bm.operator ()<std::deque<int >>(" rng::rotate(deque<int>) (by 1/3)" , std::ranges::rotate, 0.33 );
60
+ bm.operator ()<std::list<int >>(" rng::rotate(list<int>) (by 1/3)" , std::ranges::rotate, 0.33 );
61
+
62
+ bm.operator ()<std::vector<int >>(" std::rotate(vector<int>) (by 1/2)" , std_rotate, 0.50 );
63
+ bm.operator ()<std::deque<int >>(" std::rotate(deque<int>) (by 1/2)" , std_rotate, 0.50 );
64
+ bm.operator ()<std::list<int >>(" std::rotate(list<int>) (by 1/2)" , std_rotate, 0.50 );
65
+ bm.operator ()<std::vector<int >>(" rng::rotate(vector<int>) (by 1/2)" , std::ranges::rotate, 0.50 );
66
+ bm.operator ()<std::deque<int >>(" rng::rotate(deque<int>) (by 1/2)" , std::ranges::rotate, 0.50 );
67
+ bm.operator ()<std::list<int >>(" rng::rotate(list<int>) (by 1/2)" , std::ranges::rotate, 0.50 );
68
+ }
69
+
70
+ // Benchmark {std,ranges}::rotate where we rotate a single element from the beginning to the end of the range.
71
+ {
72
+ auto bm = []<class Container >(std::string name, auto rotate) {
73
+ benchmark::RegisterBenchmark (
74
+ name,
75
+ [rotate](auto & st) {
76
+ std::size_t const size = st.range (0 );
77
+ using ValueType = typename Container::value_type;
78
+ Container c;
79
+ std::generate_n (std::back_inserter (c), size, [] { return Generate<ValueType>::random (); });
80
+
81
+ auto pivot = std::next (c.begin ());
82
+ for ([[maybe_unused]] auto _ : st) {
83
+ benchmark::DoNotOptimize (c);
84
+ auto result = rotate (c.begin (), pivot, c.end ());
85
+ benchmark::DoNotOptimize (result);
86
+ }
87
+ })
88
+ ->Arg (32 )
89
+ ->Arg (1024 )
90
+ ->Arg (8192 );
91
+ };
92
+ bm.operator ()<std::vector<int >>(" std::rotate(vector<int>) (1 element forward)" , std_rotate);
93
+ bm.operator ()<std::deque<int >>(" std::rotate(deque<int>) (1 element forward)" , std_rotate);
94
+ bm.operator ()<std::list<int >>(" std::rotate(list<int>) (1 element forward)" , std_rotate);
95
+ bm.operator ()<std::vector<int >>(" rng::rotate(vector<int>) (1 element forward)" , std::ranges::rotate);
96
+ bm.operator ()<std::deque<int >>(" rng::rotate(deque<int>) (1 element forward)" , std::ranges::rotate);
97
+ bm.operator ()<std::list<int >>(" rng::rotate(list<int>) (1 element forward)" , std::ranges::rotate);
98
+ }
99
+
100
+ // Benchmark {std,ranges}::rotate where we rotate a single element from the end to the beginning of the range.
26
101
{
27
102
auto bm = []<class Container >(std::string name, auto rotate) {
28
103
benchmark::RegisterBenchmark (
@@ -33,23 +108,23 @@ int main(int argc, char** argv) {
33
108
Container c;
34
109
std::generate_n (std::back_inserter (c), size, [] { return Generate<ValueType>::random (); });
35
110
36
- auto middle = std::next (c.begin (), size / 2 );
111
+ auto pivot = std::next (c.begin (), size - 1 );
37
112
for ([[maybe_unused]] auto _ : st) {
38
113
benchmark::DoNotOptimize (c);
39
- auto result = rotate (c.begin (), middle , c.end ());
114
+ auto result = rotate (c.begin (), pivot , c.end ());
40
115
benchmark::DoNotOptimize (result);
41
116
}
42
117
})
43
118
->Arg (32 )
44
119
->Arg (1024 )
45
120
->Arg (8192 );
46
121
};
47
- bm.operator ()<std::vector<int >>(" std::rotate(vector<int>)" , std_rotate);
48
- bm.operator ()<std::deque<int >>(" std::rotate(deque<int>)" , std_rotate);
49
- bm.operator ()<std::list<int >>(" std::rotate(list<int>)" , std_rotate);
50
- bm.operator ()<std::vector<int >>(" rng::rotate(vector<int>)" , std::ranges::rotate);
51
- bm.operator ()<std::deque<int >>(" rng::rotate(deque<int>)" , std::ranges::rotate);
52
- bm.operator ()<std::list<int >>(" rng::rotate(list<int>)" , std::ranges::rotate);
122
+ bm.operator ()<std::vector<int >>(" std::rotate(vector<int>) (1 element backward) " , std_rotate);
123
+ bm.operator ()<std::deque<int >>(" std::rotate(deque<int>) (1 element backward) " , std_rotate);
124
+ bm.operator ()<std::list<int >>(" std::rotate(list<int>) (1 element backward) " , std_rotate);
125
+ bm.operator ()<std::vector<int >>(" rng::rotate(vector<int>) (1 element backward) " , std::ranges::rotate);
126
+ bm.operator ()<std::deque<int >>(" rng::rotate(deque<int>) (1 element backward) " , std::ranges::rotate);
127
+ bm.operator ()<std::list<int >>(" rng::rotate(list<int>) (1 element backward) " , std::ranges::rotate);
53
128
}
54
129
55
130
benchmark::Initialize (&argc, argv);
0 commit comments