Skip to content

Commit 232a73a

Browse files
committed
[libc++] Add remaining benchmarks from [alg.modifying.operations]
This patch adds benchmarks for all the remaining algorithms in [alg.modifying.operations] that we didn't already have a benchmark for.
1 parent 1841bcd commit 232a73a

28 files changed

+2205
-100
lines changed

libcxx/include/module.modulemap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,7 @@ module std [system] {
700700
}
701701
module ranges_remove {
702702
header "__algorithm/ranges_remove.h"
703+
export std.ranges.subrange // return type
703704
}
704705
module ranges_replace_copy_if {
705706
header "__algorithm/ranges_replace_copy_if.h"
@@ -724,7 +725,7 @@ module std [system] {
724725
}
725726
module ranges_rotate_copy {
726727
header "__algorithm/ranges_rotate_copy.h"
727-
export std.algorithm.in_out_result
728+
export std.ranges.subrange // return type
728729
}
729730
module ranges_rotate { header "__algorithm/ranges_rotate.h" }
730731
module ranges_sample { header "__algorithm/ranges_sample.h" }

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

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

0 commit comments

Comments
 (0)