Skip to content

Commit 3982902

Browse files
committed
[libc++] Refactor and add benchmarks from [alg.nonmodifying]
1 parent 29361b3 commit 3982902

26 files changed

+2052
-418
lines changed

libcxx/test/benchmarks/GenerateInput.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <climits>
1414
#include <concepts>
1515
#include <cstddef>
16+
#include <initializer_list>
1617
#include <random>
1718
#include <string>
1819
#include <vector>
@@ -204,4 +205,13 @@ struct Generate<std::string> {
204205
}
205206
};
206207

208+
template <class T>
209+
T random_different_from(std::initializer_list<T> others) {
210+
T value;
211+
do {
212+
value = Generate<T>::random();
213+
} while (std::ranges::contains(others, value));
214+
return value;
215+
}
216+
207217
#endif // BENCHMARK_GENERATE_INPUT_H

libcxx/test/benchmarks/algorithms/count.bench.cpp

Lines changed: 0 additions & 37 deletions
This file was deleted.

libcxx/test/benchmarks/algorithms/equal.bench.cpp

Lines changed: 0 additions & 48 deletions
This file was deleted.

libcxx/test/benchmarks/algorithms/find.bench.cpp

Lines changed: 0 additions & 90 deletions
This file was deleted.

libcxx/test/benchmarks/algorithms/for_each.bench.cpp

Lines changed: 0 additions & 25 deletions
This file was deleted.

libcxx/test/benchmarks/algorithms/mismatch.bench.cpp

Lines changed: 0 additions & 58 deletions
This file was deleted.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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, c++11, c++14, c++17
10+
11+
#include <algorithm>
12+
#include <cstddef>
13+
#include <deque>
14+
#include <list>
15+
#include <string>
16+
#include <vector>
17+
18+
#include <benchmark/benchmark.h>
19+
#include "../../GenerateInput.h"
20+
21+
int main(int argc, char** argv) {
22+
auto std_adjacent_find = [](auto first, auto last) { return std::adjacent_find(first, last); };
23+
auto std_adjacent_find_pred = [](auto first, auto last) {
24+
return std::adjacent_find(first, last, [](auto x, auto y) {
25+
benchmark::DoNotOptimize(x);
26+
benchmark::DoNotOptimize(y);
27+
return x == y;
28+
});
29+
};
30+
auto ranges_adjacent_find_pred = [](auto first, auto last) {
31+
return std::ranges::adjacent_find(first, last, [](auto x, auto y) {
32+
benchmark::DoNotOptimize(x);
33+
benchmark::DoNotOptimize(y);
34+
return x == y;
35+
});
36+
};
37+
38+
// Benchmark {std,ranges}::adjacent_find on a sequence of the form xyxyxyxyxyxyxyxyxyxy,
39+
// which means we never find adjacent equal elements (the worst case of the algorithm).
40+
{
41+
auto bm = []<class Container>(std::string name, auto adjacent_find) {
42+
benchmark::RegisterBenchmark(
43+
name,
44+
[adjacent_find](auto& st) {
45+
std::size_t const size = st.range(0);
46+
using ValueType = typename Container::value_type;
47+
ValueType x = Generate<ValueType>::random();
48+
ValueType y = random_different_from({x});
49+
Container c;
50+
for (std::size_t i = 0; i != size; ++i) {
51+
c.push_back(i % 2 == 0 ? x : y);
52+
}
53+
54+
for ([[maybe_unused]] auto _ : st) {
55+
benchmark::DoNotOptimize(c);
56+
auto result = adjacent_find(c.begin(), c.end());
57+
benchmark::DoNotOptimize(result);
58+
}
59+
})
60+
->Arg(8)
61+
->Arg(1024)
62+
->Arg(8192)
63+
->Arg(1 << 20);
64+
};
65+
66+
// {std,ranges}::adjacent_find
67+
bm.operator()<std::vector<int>>("std::adjacent_find(vector<int>)", std_adjacent_find);
68+
bm.operator()<std::deque<int>>("std::adjacent_find(deque<int>)", std_adjacent_find);
69+
bm.operator()<std::list<int>>("std::adjacent_find(list<int>)", std_adjacent_find);
70+
bm.operator()<std::vector<int>>("rng::adjacent_find(vector<int>)", std::ranges::adjacent_find);
71+
bm.operator()<std::deque<int>>("rng::adjacent_find(deque<int>)", std::ranges::adjacent_find);
72+
bm.operator()<std::list<int>>("rng::adjacent_find(list<int>)", std::ranges::adjacent_find);
73+
74+
// {std,ranges}::adjacent_find(pred)
75+
bm.operator()<std::vector<int>>("std::adjacent_find(vector<int>, pred)", std_adjacent_find_pred);
76+
bm.operator()<std::deque<int>>("std::adjacent_find(deque<int>, pred)", std_adjacent_find_pred);
77+
bm.operator()<std::list<int>>("std::adjacent_find(list<int>, pred)", std_adjacent_find_pred);
78+
bm.operator()<std::vector<int>>("rng::adjacent_find(vector<int>, pred)", ranges_adjacent_find_pred);
79+
bm.operator()<std::deque<int>>("rng::adjacent_find(deque<int>, pred)", ranges_adjacent_find_pred);
80+
bm.operator()<std::list<int>>("rng::adjacent_find(list<int>, pred)", ranges_adjacent_find_pred);
81+
}
82+
83+
benchmark::Initialize(&argc, argv);
84+
benchmark::RunSpecifiedBenchmarks();
85+
benchmark::Shutdown();
86+
return 0;
87+
}

0 commit comments

Comments
 (0)