Skip to content

Commit a302cf8

Browse files
committed
Review comments for std::search
1 parent 86e9b0e commit a302cf8

File tree

1 file changed

+83
-2
lines changed

1 file changed

+83
-2
lines changed

libcxx/test/benchmarks/algorithms/nonmodifying/search.bench.cpp

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int main(int argc, char** argv) {
3838
});
3939
};
4040

41-
// Benchmark {std,ranges}::search where the needle is never found
41+
// Benchmark {std,ranges}::search where the needle is never found (worst case).
4242
{
4343
auto bm = []<class Container>(std::string name, auto search) {
4444
benchmark::RegisterBenchmark(
@@ -80,7 +80,7 @@ int main(int argc, char** argv) {
8080
bm.operator()<std::list<int>>("rng::search(list<int>, pred) (no match)", ranges_search_pred);
8181
}
8282

83-
// Benchmark {std,ranges}::search where we intersperse "near matches" inside the haystack
83+
// Benchmark {std,ranges}::search where we intersperse "near matches" inside the haystack.
8484
{
8585
auto bm = []<class Container>(std::string name, auto search) {
8686
benchmark::RegisterBenchmark(
@@ -132,6 +132,87 @@ int main(int argc, char** argv) {
132132
bm.operator()<std::list<int>>("rng::search(list<int>, pred) (near matches)", ranges_search_pred);
133133
}
134134

135+
// Special case: the two ranges are the same length (and they are equal, which is the worst case).
136+
{
137+
auto bm = []<class Container>(std::string name, auto search) {
138+
benchmark::RegisterBenchmark(
139+
name,
140+
[search](auto& st) {
141+
std::size_t const size = st.range(0);
142+
using ValueType = typename Container::value_type;
143+
ValueType x = Generate<ValueType>::random();
144+
Container haystack(size, x);
145+
Container needle(size, x);
146+
147+
for ([[maybe_unused]] auto _ : st) {
148+
benchmark::DoNotOptimize(haystack);
149+
benchmark::DoNotOptimize(needle);
150+
auto result = search(haystack.begin(), haystack.end(), needle.begin(), needle.end());
151+
benchmark::DoNotOptimize(result);
152+
}
153+
})
154+
->Arg(1000) // non power-of-two
155+
->Arg(1024)
156+
->Arg(8192);
157+
};
158+
// {std,ranges}::search
159+
bm.operator()<std::vector<int>>("std::search(vector<int>) (same length)", std_search);
160+
bm.operator()<std::deque<int>>("std::search(deque<int>) (same length)", std_search);
161+
bm.operator()<std::list<int>>("std::search(list<int>) (same length)", std_search);
162+
bm.operator()<std::vector<int>>("rng::search(vector<int>) (same length)", std::ranges::search);
163+
bm.operator()<std::deque<int>>("rng::search(deque<int>) (same length)", std::ranges::search);
164+
bm.operator()<std::list<int>>("rng::search(list<int>) (same length)", std::ranges::search);
165+
166+
// {std,ranges}::search(pred)
167+
bm.operator()<std::vector<int>>("std::search(vector<int>, pred) (same length)", std_search_pred);
168+
bm.operator()<std::deque<int>>("std::search(deque<int>, pred) (same length)", std_search_pred);
169+
bm.operator()<std::list<int>>("std::search(list<int>, pred) (same length)", std_search_pred);
170+
bm.operator()<std::vector<int>>("rng::search(vector<int>, pred) (same length)", ranges_search_pred);
171+
bm.operator()<std::deque<int>>("rng::search(deque<int>, pred) (same length)", ranges_search_pred);
172+
bm.operator()<std::list<int>>("rng::search(list<int>, pred) (same length)", ranges_search_pred);
173+
}
174+
175+
// Special case: the needle contains a single element (which we never find, i.e. the worst case).
176+
{
177+
auto bm = []<class Container>(std::string name, auto search) {
178+
benchmark::RegisterBenchmark(
179+
name,
180+
[search](auto& st) {
181+
std::size_t const size = st.range(0);
182+
using ValueType = typename Container::value_type;
183+
ValueType x = Generate<ValueType>::random();
184+
ValueType y = random_different_from({x});
185+
Container haystack(size, x);
186+
Container needle(1, y);
187+
188+
for ([[maybe_unused]] auto _ : st) {
189+
benchmark::DoNotOptimize(haystack);
190+
benchmark::DoNotOptimize(needle);
191+
auto result = search(haystack.begin(), haystack.end(), needle.begin(), needle.end());
192+
benchmark::DoNotOptimize(result);
193+
}
194+
})
195+
->Arg(1000) // non power-of-two
196+
->Arg(1024)
197+
->Arg(8192);
198+
};
199+
// {std,ranges}::search
200+
bm.operator()<std::vector<int>>("std::search(vector<int>) (single element)", std_search);
201+
bm.operator()<std::deque<int>>("std::search(deque<int>) (single element)", std_search);
202+
bm.operator()<std::list<int>>("std::search(list<int>) (single element)", std_search);
203+
bm.operator()<std::vector<int>>("rng::search(vector<int>) (single element)", std::ranges::search);
204+
bm.operator()<std::deque<int>>("rng::search(deque<int>) (single element)", std::ranges::search);
205+
bm.operator()<std::list<int>>("rng::search(list<int>) (single element)", std::ranges::search);
206+
207+
// {std,ranges}::search(pred)
208+
bm.operator()<std::vector<int>>("std::search(vector<int>, pred) (single element)", std_search_pred);
209+
bm.operator()<std::deque<int>>("std::search(deque<int>, pred) (single element)", std_search_pred);
210+
bm.operator()<std::list<int>>("std::search(list<int>, pred) (single element)", std_search_pred);
211+
bm.operator()<std::vector<int>>("rng::search(vector<int>, pred) (single element)", ranges_search_pred);
212+
bm.operator()<std::deque<int>>("rng::search(deque<int>, pred) (single element)", ranges_search_pred);
213+
bm.operator()<std::list<int>>("rng::search(list<int>, pred) (single element)", ranges_search_pred);
214+
}
215+
135216
benchmark::Initialize(&argc, argv);
136217
benchmark::RunSpecifiedBenchmarks();
137218
benchmark::Shutdown();

0 commit comments

Comments
 (0)