Skip to content

Commit 24e88b0

Browse files
authored
[libc++] Add remaining benchmarks from [alg.modifying.operations] (#127354)
This patch adds benchmarks for all the remaining algorithms in [alg.modifying.operations] that we didn't already have a benchmark for.
1 parent 911b200 commit 24e88b0

28 files changed

+1968
-247
lines changed

libcxx/include/module.modulemap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,7 @@ module std [system] {
708708
}
709709
module ranges_remove {
710710
header "__algorithm/ranges_remove.h"
711+
export std.ranges.subrange // return type
711712
}
712713
module ranges_replace_copy_if {
713714
header "__algorithm/ranges_replace_copy_if.h"
@@ -732,7 +733,7 @@ module std [system] {
732733
}
733734
module ranges_rotate_copy {
734735
header "__algorithm/ranges_rotate_copy.h"
735-
export std.algorithm.in_out_result
736+
export std.ranges.subrange // return type
736737
}
737738
module ranges_rotate { header "__algorithm/ranges_rotate.h" }
738739
module ranges_sample { header "__algorithm/ranges_sample.h" }

libcxx/test/benchmarks/GenerateInput.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,13 @@ struct Generate<std::string> {
204204
}
205205
};
206206

207+
template <class T>
208+
T random_different_from(std::initializer_list<T> others) {
209+
T value;
210+
do {
211+
value = Generate<T>::random();
212+
} while (std::find(others.begin(), others.end(), value) != others.end());
213+
return value;
214+
}
215+
207216
#endif // BENCHMARK_GENERATE_INPUT_H

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

Lines changed: 0 additions & 51 deletions
This file was deleted.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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 <iterator>
15+
#include <list>
16+
#include <string>
17+
#include <vector>
18+
19+
#include "benchmark/benchmark.h"
20+
#include "../../GenerateInput.h"
21+
#include "test_macros.h"
22+
23+
int main(int argc, char** argv) {
24+
auto std_fill = [](auto first, auto last, auto const& value) { return std::fill(first, last, value); };
25+
26+
// {std,ranges}::fill(normal container)
27+
{
28+
auto bm = []<class Container>(std::string name, auto fill) {
29+
benchmark::RegisterBenchmark(
30+
name,
31+
[fill](auto& st) {
32+
std::size_t const size = st.range(0);
33+
using ValueType = typename Container::value_type;
34+
ValueType x = Generate<ValueType>::random();
35+
Container c(size, x);
36+
37+
for ([[maybe_unused]] auto _ : st) {
38+
benchmark::DoNotOptimize(c);
39+
benchmark::DoNotOptimize(x);
40+
fill(c.begin(), c.end(), x);
41+
benchmark::DoNotOptimize(c);
42+
}
43+
})
44+
->Arg(32)
45+
->Arg(50) // non power-of-two
46+
->Arg(1024)
47+
->Arg(8192);
48+
};
49+
bm.operator()<std::vector<int>>("std::fill(vector<int>)", std_fill);
50+
bm.operator()<std::deque<int>>("std::fill(deque<int>)", std_fill);
51+
bm.operator()<std::list<int>>("std::fill(list<int>)", std_fill);
52+
bm.operator()<std::vector<int>>("rng::fill(vector<int>)", std::ranges::fill);
53+
bm.operator()<std::deque<int>>("rng::fill(deque<int>)", std::ranges::fill);
54+
bm.operator()<std::list<int>>("rng::fill(list<int>)", std::ranges::fill);
55+
}
56+
57+
// {std,ranges}::fill(vector<bool>)
58+
{
59+
auto bm = [](std::string name, auto fill) {
60+
benchmark::RegisterBenchmark(name, [fill](auto& st) {
61+
std::size_t const size = st.range(0);
62+
bool x = true;
63+
std::vector<bool> c(size, x);
64+
65+
for ([[maybe_unused]] auto _ : st) {
66+
benchmark::DoNotOptimize(c);
67+
benchmark::DoNotOptimize(x);
68+
fill(c.begin(), c.end(), x);
69+
benchmark::DoNotOptimize(c);
70+
}
71+
})->Range(64, 1 << 20);
72+
};
73+
bm("std::fill(vector<bool>)", std_fill);
74+
#if TEST_STD_VER >= 23 // vector<bool>::iterator is not an output_iterator before C++23
75+
bm("rng::fill(vector<bool>)", std::ranges::fill);
76+
#endif
77+
}
78+
79+
benchmark::Initialize(&argc, argv);
80+
benchmark::RunSpecifiedBenchmarks();
81+
benchmark::Shutdown();
82+
return 0;
83+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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 <iterator>
15+
#include <list>
16+
#include <string>
17+
#include <vector>
18+
19+
#include "benchmark/benchmark.h"
20+
#include "../../GenerateInput.h"
21+
#include "test_macros.h"
22+
23+
int main(int argc, char** argv) {
24+
auto std_fill_n = [](auto out, auto n, auto const& value) { return std::fill_n(out, n, value); };
25+
26+
// {std,ranges}::fill_n(normal container)
27+
{
28+
auto bm = []<class Container>(std::string name, auto fill_n) {
29+
benchmark::RegisterBenchmark(
30+
name,
31+
[fill_n](auto& st) {
32+
std::size_t const size = st.range(0);
33+
using ValueType = typename Container::value_type;
34+
ValueType x = Generate<ValueType>::random();
35+
Container c(size, x);
36+
37+
for ([[maybe_unused]] auto _ : st) {
38+
benchmark::DoNotOptimize(c);
39+
benchmark::DoNotOptimize(x);
40+
fill_n(c.begin(), size, x);
41+
benchmark::DoNotOptimize(c);
42+
}
43+
})
44+
->Arg(32)
45+
->Arg(50) // non power-of-two
46+
->Arg(1024)
47+
->Arg(8192);
48+
};
49+
bm.operator()<std::vector<int>>("std::fill_n(vector<int>)", std_fill_n);
50+
bm.operator()<std::deque<int>>("std::fill_n(deque<int>)", std_fill_n);
51+
bm.operator()<std::list<int>>("std::fill_n(list<int>)", std_fill_n);
52+
bm.operator()<std::vector<int>>("rng::fill_n(vector<int>)", std::ranges::fill_n);
53+
bm.operator()<std::deque<int>>("rng::fill_n(deque<int>)", std::ranges::fill_n);
54+
bm.operator()<std::list<int>>("rng::fill_n(list<int>)", std::ranges::fill_n);
55+
}
56+
57+
// {std,ranges}::fill_n(vector<bool>)
58+
{
59+
auto bm = [](std::string name, auto fill_n) {
60+
benchmark::RegisterBenchmark(name, [fill_n](auto& st) {
61+
std::size_t const size = st.range(0);
62+
bool x = true;
63+
std::vector<bool> c(size, x);
64+
65+
for ([[maybe_unused]] auto _ : st) {
66+
benchmark::DoNotOptimize(c);
67+
benchmark::DoNotOptimize(x);
68+
fill_n(c.begin(), size, x);
69+
benchmark::DoNotOptimize(c);
70+
}
71+
})->Range(64, 1 << 20);
72+
};
73+
bm("std::fill_n(vector<bool>)", std_fill_n);
74+
#if TEST_STD_VER >= 23 // vector<bool>::iterator is not an output_iterator before C++23
75+
bm("rng::fill_n(vector<bool>)", std::ranges::fill_n);
76+
#endif
77+
}
78+
79+
benchmark::Initialize(&argc, argv);
80+
benchmark::RunSpecifiedBenchmarks();
81+
benchmark::Shutdown();
82+
return 0;
83+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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 <iterator>
15+
#include <list>
16+
#include <string>
17+
#include <vector>
18+
19+
#include "benchmark/benchmark.h"
20+
#include "../../GenerateInput.h"
21+
22+
int main(int argc, char** argv) {
23+
auto std_generate = [](auto first, auto last, auto f) { return std::generate(first, last, f); };
24+
25+
// {std,ranges}::generate
26+
{
27+
auto bm = []<class Container>(std::string name, auto generate) {
28+
benchmark::RegisterBenchmark(
29+
name,
30+
[generate](auto& st) {
31+
std::size_t const size = st.range(0);
32+
Container c(size);
33+
using ValueType = typename Container::value_type;
34+
ValueType x = Generate<ValueType>::random();
35+
36+
for ([[maybe_unused]] auto _ : st) {
37+
benchmark::DoNotOptimize(c);
38+
generate(c.begin(), c.end(), [&x] {
39+
benchmark::DoNotOptimize(x);
40+
return x;
41+
});
42+
benchmark::DoNotOptimize(c);
43+
}
44+
})
45+
->Arg(32)
46+
->Arg(50) // non power-of-two
47+
->Arg(1024)
48+
->Arg(8192);
49+
};
50+
bm.operator()<std::vector<int>>("std::generate(vector<int>)", std_generate);
51+
bm.operator()<std::deque<int>>("std::generate(deque<int>)", std_generate);
52+
bm.operator()<std::list<int>>("std::generate(list<int>)", std_generate);
53+
bm.operator()<std::vector<int>>("rng::generate(vector<int>)", std::ranges::generate);
54+
bm.operator()<std::deque<int>>("rng::generate(deque<int>)", std::ranges::generate);
55+
bm.operator()<std::list<int>>("rng::generate(list<int>)", std::ranges::generate);
56+
}
57+
58+
benchmark::Initialize(&argc, argv);
59+
benchmark::RunSpecifiedBenchmarks();
60+
benchmark::Shutdown();
61+
return 0;
62+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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 <iterator>
15+
#include <list>
16+
#include <string>
17+
#include <vector>
18+
19+
#include "benchmark/benchmark.h"
20+
#include "../../GenerateInput.h"
21+
22+
int main(int argc, char** argv) {
23+
auto std_generate_n = [](auto out, auto n, auto f) { return std::generate_n(out, n, f); };
24+
25+
// {std,ranges}::generate_n
26+
{
27+
auto bm = []<class Container>(std::string name, auto generate_n) {
28+
benchmark::RegisterBenchmark(
29+
name,
30+
[generate_n](auto& st) {
31+
std::size_t const size = st.range(0);
32+
Container c(size);
33+
using ValueType = typename Container::value_type;
34+
ValueType x = Generate<ValueType>::random();
35+
36+
for ([[maybe_unused]] auto _ : st) {
37+
benchmark::DoNotOptimize(c);
38+
generate_n(c.begin(), size, [&x] {
39+
benchmark::DoNotOptimize(x);
40+
return x;
41+
});
42+
benchmark::DoNotOptimize(c);
43+
}
44+
})
45+
->Arg(32)
46+
->Arg(50) // non power-of-two
47+
->Arg(1024)
48+
->Arg(8192);
49+
};
50+
bm.operator()<std::vector<int>>("std::generate_n(vector<int>)", std_generate_n);
51+
bm.operator()<std::deque<int>>("std::generate_n(deque<int>)", std_generate_n);
52+
bm.operator()<std::list<int>>("std::generate_n(list<int>)", std_generate_n);
53+
bm.operator()<std::vector<int>>("rng::generate_n(vector<int>)", std::ranges::generate_n);
54+
bm.operator()<std::deque<int>>("rng::generate_n(deque<int>)", std::ranges::generate_n);
55+
bm.operator()<std::list<int>>("rng::generate_n(list<int>)", std::ranges::generate_n);
56+
}
57+
58+
benchmark::Initialize(&argc, argv);
59+
benchmark::RunSpecifiedBenchmarks();
60+
benchmark::Shutdown();
61+
return 0;
62+
}

0 commit comments

Comments
 (0)