Skip to content

Commit ef203af

Browse files
committed
Improve coverage for rotate
1 parent c50f43f commit ef203af

File tree

1 file changed

+84
-9
lines changed

1 file changed

+84
-9
lines changed

libcxx/test/benchmarks/algorithms/modifying/rotate.bench.cpp

Lines changed: 84 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,82 @@
2222
int main(int argc, char** argv) {
2323
auto std_rotate = [](auto first, auto middle, auto last) { return std::rotate(first, middle, last); };
2424

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.
26101
{
27102
auto bm = []<class Container>(std::string name, auto rotate) {
28103
benchmark::RegisterBenchmark(
@@ -33,23 +108,23 @@ int main(int argc, char** argv) {
33108
Container c;
34109
std::generate_n(std::back_inserter(c), size, [] { return Generate<ValueType>::random(); });
35110

36-
auto middle = std::next(c.begin(), size / 2);
111+
auto pivot = std::next(c.begin(), size - 1);
37112
for ([[maybe_unused]] auto _ : st) {
38113
benchmark::DoNotOptimize(c);
39-
auto result = rotate(c.begin(), middle, c.end());
114+
auto result = rotate(c.begin(), pivot, c.end());
40115
benchmark::DoNotOptimize(result);
41116
}
42117
})
43118
->Arg(32)
44119
->Arg(1024)
45120
->Arg(8192);
46121
};
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);
53128
}
54129

55130
benchmark::Initialize(&argc, argv);

0 commit comments

Comments
 (0)