Skip to content

Commit d34de3e

Browse files
committed
Implement consensus with Nikolas
1 parent d672c6d commit d34de3e

File tree

4 files changed

+210
-223
lines changed

4 files changed

+210
-223
lines changed

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

Lines changed: 49 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -20,64 +20,61 @@
2020
#include "../../GenerateInput.h"
2121
#include "test_macros.h"
2222

23-
template <class Container, class Operation>
24-
void bm_general(std::string operation_name, Operation copy) {
25-
auto bench = [copy](auto& st) {
26-
std::size_t const n = st.range(0);
27-
using ValueType = typename Container::value_type;
28-
Container c;
29-
std::generate_n(std::back_inserter(c), n, [] { return Generate<ValueType>::random(); });
30-
31-
std::vector<ValueType> out(n);
32-
33-
for ([[maybe_unused]] auto _ : st) {
34-
benchmark::DoNotOptimize(c);
35-
benchmark::DoNotOptimize(out);
36-
auto result = copy(c.begin(), c.end(), out.begin());
37-
benchmark::DoNotOptimize(result);
38-
}
39-
};
40-
benchmark::RegisterBenchmark(operation_name, bench)->Range(8, 1 << 20);
41-
}
23+
int main(int argc, char** argv) {
24+
auto std_copy = [](auto first, auto last, auto out) { return std::copy(first, last, out); };
4225

43-
template <bool Aligned, class Operation>
44-
static void bm_vector_bool(std::string operation_name, Operation copy) {
45-
auto bench = [copy](auto& st) {
46-
std::size_t const n = st.range(0);
47-
std::vector<bool> in(n, true);
48-
std::vector<bool> out(Aligned ? n : n + 8);
49-
auto first = in.begin();
50-
auto last = in.end();
51-
auto dst = Aligned ? out.begin() : out.begin() + 4;
52-
for ([[maybe_unused]] auto _ : st) {
53-
benchmark::DoNotOptimize(in);
54-
benchmark::DoNotOptimize(out);
55-
auto result = copy(first, last, dst);
56-
benchmark::DoNotOptimize(result);
57-
}
58-
};
59-
benchmark::RegisterBenchmark(operation_name, bench)->Range(64, 1 << 20);
60-
}
26+
// {std,ranges}::copy(normal container)
27+
{
28+
auto bm = []<class Container>(std::string name, auto copy) {
29+
benchmark::RegisterBenchmark(name, [copy](auto& st) {
30+
std::size_t const n = st.range(0);
31+
using ValueType = typename Container::value_type;
32+
Container c;
33+
std::generate_n(std::back_inserter(c), n, [] { return Generate<ValueType>::random(); });
6134

62-
int main(int argc, char** argv) {
63-
auto std_copy = [](auto first, auto last, auto out) { return std::copy(first, last, out); };
64-
auto ranges_copy = std::ranges::copy;
35+
std::vector<ValueType> out(n);
6536

66-
// std::copy
67-
bm_general<std::vector<int>>("std::copy(vector<int>)", std_copy);
68-
bm_general<std::deque<int>>("std::copy(deque<int>)", std_copy);
69-
bm_general<std::list<int>>("std::copy(list<int>)", std_copy);
70-
bm_vector_bool<true>("std::copy(vector<bool>) (aligned)", std_copy);
71-
bm_vector_bool<false>("std::copy(vector<bool>) (unaligned)", std_copy);
37+
for ([[maybe_unused]] auto _ : st) {
38+
benchmark::DoNotOptimize(c);
39+
benchmark::DoNotOptimize(out);
40+
auto result = copy(c.begin(), c.end(), out.begin());
41+
benchmark::DoNotOptimize(result);
42+
}
43+
})->Range(8, 1 << 20);
44+
};
45+
bm.operator()<std::vector<int>>("std::copy(vector<int>)", std_copy);
46+
bm.operator()<std::deque<int>>("std::copy(deque<int>)", std_copy);
47+
bm.operator()<std::list<int>>("std::copy(list<int>)", std_copy);
48+
bm.operator()<std::vector<int>>("ranges::copy(vector<int>)", std::ranges::copy);
49+
bm.operator()<std::deque<int>>("ranges::copy(deque<int>)", std::ranges::copy);
50+
bm.operator()<std::list<int>>("ranges::copy(list<int>)", std::ranges::copy);
51+
}
7252

73-
// ranges::copy
74-
bm_general<std::vector<int>>("ranges::copy(vector<int>)", ranges_copy);
75-
bm_general<std::deque<int>>("ranges::copy(deque<int>)", ranges_copy);
76-
bm_general<std::list<int>>("ranges::copy(list<int>)", ranges_copy);
53+
// {std,ranges}::copy(vector<bool>)
54+
{
55+
auto bm = []<bool Aligned>(std::string name, auto copy) {
56+
benchmark::RegisterBenchmark(name, [copy](auto& st) {
57+
std::size_t const n = st.range(0);
58+
std::vector<bool> in(n, true);
59+
std::vector<bool> out(Aligned ? n : n + 8);
60+
auto first = in.begin();
61+
auto last = in.end();
62+
auto dst = Aligned ? out.begin() : out.begin() + 4;
63+
for ([[maybe_unused]] auto _ : st) {
64+
benchmark::DoNotOptimize(in);
65+
benchmark::DoNotOptimize(out);
66+
auto result = copy(first, last, dst);
67+
benchmark::DoNotOptimize(result);
68+
}
69+
})->Range(64, 1 << 20);
70+
};
71+
bm.operator()<true>("std::copy(vector<bool>) (aligned)", std_copy);
72+
bm.operator()<false>("std::copy(vector<bool>) (unaligned)", std_copy);
7773
#if TEST_STD_VER >= 23 // vector<bool>::iterator is not an output_iterator before C++23
78-
bm_vector_bool<true>("ranges::copy(vector<bool>) (aligned)", ranges_copy);
79-
bm_vector_bool<false>("ranges::copy(vector<bool>) (unaligned)", ranges_copy);
74+
bm.operator()<true>("ranges::copy(vector<bool>) (aligned)", std::ranges::copy);
75+
bm.operator()<false>("ranges::copy(vector<bool>) (unaligned)", std::ranges::copy);
8076
#endif
77+
}
8178

8279
benchmark::Initialize(&argc, argv);
8380
benchmark::RunSpecifiedBenchmarks();

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

Lines changed: 50 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -20,65 +20,62 @@
2020
#include "../../GenerateInput.h"
2121
#include "test_macros.h"
2222

23-
template <class Container, class Operation>
24-
void bm_general(std::string operation_name, Operation copy_backward) {
25-
auto bench = [copy_backward](auto& st) {
26-
std::size_t const n = st.range(0);
27-
using ValueType = typename Container::value_type;
28-
Container c;
29-
std::generate_n(std::back_inserter(c), n, [] { return Generate<ValueType>::random(); });
30-
31-
std::vector<ValueType> out(n);
32-
33-
for ([[maybe_unused]] auto _ : st) {
34-
benchmark::DoNotOptimize(c);
35-
benchmark::DoNotOptimize(out);
36-
auto result = copy_backward(c.begin(), c.end(), out.end());
37-
benchmark::DoNotOptimize(result);
38-
}
39-
};
40-
benchmark::RegisterBenchmark(operation_name, bench)->Range(8, 1 << 20);
41-
}
23+
int main(int argc, char** argv) {
24+
auto std_copy_backward = [](auto first, auto last, auto out) { return std::copy_backward(first, last, out); };
4225

43-
template <bool Aligned, class Operation>
44-
static void bm_vector_bool(std::string operation_name, Operation copy_backward) {
45-
auto bench = [copy_backward](auto& st) {
46-
std::size_t const n = st.range(0);
47-
std::vector<bool> in(n, true);
48-
std::vector<bool> out(Aligned ? n : n + 8);
49-
benchmark::DoNotOptimize(&in);
50-
auto first = in.begin();
51-
auto last = in.end();
52-
auto dst = Aligned ? out.end() : out.end() - 4;
53-
for ([[maybe_unused]] auto _ : st) {
54-
benchmark::DoNotOptimize(in);
55-
benchmark::DoNotOptimize(out);
56-
auto result = copy_backward(first, last, dst);
57-
benchmark::DoNotOptimize(result);
58-
}
59-
};
60-
benchmark::RegisterBenchmark(operation_name, bench)->Range(64, 1 << 20);
61-
}
26+
// {std,ranges}::copy_n(normal container)
27+
{
28+
auto bm = []<class Container>(std::string name, auto copy_backward) {
29+
benchmark::RegisterBenchmark(name, [copy_backward](auto& st) {
30+
std::size_t const n = st.range(0);
31+
using ValueType = typename Container::value_type;
32+
Container c;
33+
std::generate_n(std::back_inserter(c), n, [] { return Generate<ValueType>::random(); });
6234

63-
int main(int argc, char** argv) {
64-
auto std_copy_backward = [](auto first, auto last, auto out) { return std::copy_backward(first, last, out); };
65-
auto ranges_copy_backward = std::ranges::copy_backward;
35+
std::vector<ValueType> out(n);
6636

67-
// std::copy
68-
bm_general<std::vector<int>>("std::copy_backward(vector<int>)", std_copy_backward);
69-
bm_general<std::deque<int>>("std::copy_backward(deque<int>)", std_copy_backward);
70-
bm_general<std::list<int>>("std::copy_backward(list<int>)", std_copy_backward);
71-
bm_vector_bool<true>("std::copy_backward(vector<bool>) (aligned)", std_copy_backward);
72-
bm_vector_bool<false>("std::copy_backward(vector<bool>) (unaligned)", std_copy_backward);
37+
for ([[maybe_unused]] auto _ : st) {
38+
benchmark::DoNotOptimize(c);
39+
benchmark::DoNotOptimize(out);
40+
auto result = copy_backward(c.begin(), c.end(), out.end());
41+
benchmark::DoNotOptimize(result);
42+
}
43+
})->Range(8, 1 << 20);
44+
};
45+
bm.operator()<std::vector<int>>("std::copy_backward(vector<int>)", std_copy_backward);
46+
bm.operator()<std::deque<int>>("std::copy_backward(deque<int>)", std_copy_backward);
47+
bm.operator()<std::list<int>>("std::copy_backward(list<int>)", std_copy_backward);
48+
bm.operator()<std::vector<int>>("ranges::copy_backward(vector<int>)", std::ranges::copy_backward);
49+
bm.operator()<std::deque<int>>("ranges::copy_backward(deque<int>)", std::ranges::copy_backward);
50+
bm.operator()<std::list<int>>("ranges::copy_backward(list<int>)", std::ranges::copy_backward);
51+
}
7352

74-
// ranges::copy
75-
bm_general<std::vector<int>>("ranges::copy_backward(vector<int>)", ranges_copy_backward);
76-
bm_general<std::deque<int>>("ranges::copy_backward(deque<int>)", ranges_copy_backward);
77-
bm_general<std::list<int>>("ranges::copy_backward(list<int>)", ranges_copy_backward);
53+
// {std,ranges}::copy_n(vector<bool>)
54+
{
55+
auto bm = []<bool Aligned>(std::string name, auto copy_backward) {
56+
benchmark::RegisterBenchmark(name, [copy_backward](auto& st) {
57+
std::size_t const n = st.range(0);
58+
std::vector<bool> in(n, true);
59+
std::vector<bool> out(Aligned ? n : n + 8);
60+
benchmark::DoNotOptimize(&in);
61+
auto first = in.begin();
62+
auto last = in.end();
63+
auto dst = Aligned ? out.end() : out.end() - 4;
64+
for ([[maybe_unused]] auto _ : st) {
65+
benchmark::DoNotOptimize(in);
66+
benchmark::DoNotOptimize(out);
67+
auto result = copy_backward(first, last, dst);
68+
benchmark::DoNotOptimize(result);
69+
}
70+
})->Range(64, 1 << 20);
71+
};
72+
bm.operator()<true>("std::copy_backward(vector<bool>) (aligned)", std_copy_backward);
73+
bm.operator()<false>("std::copy_backward(vector<bool>) (unaligned)", std_copy_backward);
7874
#if TEST_STD_VER >= 23 // vector<bool>::iterator is not an output_iterator before C++23
79-
bm_vector_bool<true>("ranges::copy_backward(vector<bool>) (aligned)", ranges_copy_backward);
80-
bm_vector_bool<false>("ranges::copy_backward(vector<bool>) (unaligned)", ranges_copy_backward);
75+
bm.operator()<true>("ranges::copy_backward(vector<bool>) (aligned)", std::ranges::copy_backward);
76+
bm.operator()<false>("ranges::copy_backward(vector<bool>) (unaligned)", std::ranges::copy_backward);
8177
#endif
78+
}
8279

8380
benchmark::Initialize(&argc, argv);
8481
benchmark::RunSpecifiedBenchmarks();

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

Lines changed: 63 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -19,81 +19,77 @@
1919
#include "benchmark/benchmark.h"
2020
#include "../../GenerateInput.h"
2121

22-
// Benchmark copying one out of two element, in alternance. This is basically
23-
// the worst case for this algorithm, I don't think there are many optimizations
24-
// that can be applied in this case.
25-
template <class Container, class Operation>
26-
void bm_copy_every_other_element(std::string operation_name, Operation copy_if) {
27-
auto bench = [copy_if](auto& st) {
28-
std::size_t const n = st.range(0);
29-
using ValueType = typename Container::value_type;
30-
Container c;
31-
std::generate_n(std::back_inserter(c), n, [] { return Generate<ValueType>::random(); });
32-
33-
std::vector<ValueType> out(n);
34-
35-
for ([[maybe_unused]] auto _ : st) {
36-
bool do_copy = false;
37-
auto pred = [&do_copy](auto& element) {
38-
benchmark::DoNotOptimize(element);
39-
do_copy = !do_copy;
40-
return do_copy;
41-
};
42-
benchmark::DoNotOptimize(c);
43-
benchmark::DoNotOptimize(out);
44-
auto result = copy_if(c.begin(), c.end(), out.begin(), pred);
45-
benchmark::DoNotOptimize(result);
46-
}
47-
};
48-
benchmark::RegisterBenchmark(operation_name, bench)->Range(8, 1 << 20);
49-
}
22+
int main(int argc, char** argv) {
23+
auto std_copy_if = [](auto first, auto last, auto out, auto pred) { return std::copy_if(first, last, out, pred); };
5024

51-
// Copy the full range.
52-
template <class Container, class Operation>
53-
void bm_copy_entire_range(std::string operation_name, Operation copy_if) {
54-
auto bench = [copy_if](auto& st) {
55-
std::size_t const n = st.range(0);
56-
using ValueType = typename Container::value_type;
57-
Container c;
58-
std::generate_n(std::back_inserter(c), n, [] { return Generate<ValueType>::random(); });
25+
// Benchmark {std,ranges}::copy_if where we copy one out of two element, in alternance.
26+
// This is basically the worst case for this algorithm, I don't think there are many
27+
// optimizations that can be applied in this case.
28+
{
29+
auto bm = []<class Container>(std::string name, auto copy_if) {
30+
benchmark::RegisterBenchmark(name, [copy_if](auto& st) {
31+
std::size_t const n = st.range(0);
32+
using ValueType = typename Container::value_type;
33+
Container c;
34+
std::generate_n(std::back_inserter(c), n, [] { return Generate<ValueType>::random(); });
5935

60-
std::vector<ValueType> out(n);
36+
std::vector<ValueType> out(n);
6137

62-
for ([[maybe_unused]] auto _ : st) {
63-
auto pred = [](auto& element) {
64-
benchmark::DoNotOptimize(element);
65-
return true;
66-
};
67-
benchmark::DoNotOptimize(c);
68-
benchmark::DoNotOptimize(out);
69-
auto result = copy_if(c.begin(), c.end(), out.begin(), pred);
70-
benchmark::DoNotOptimize(result);
71-
}
72-
};
73-
benchmark::RegisterBenchmark(operation_name, bench)->Range(8, 1 << 20);
74-
}
38+
for ([[maybe_unused]] auto _ : st) {
39+
bool do_copy = false;
40+
auto pred = [&do_copy](auto& element) {
41+
benchmark::DoNotOptimize(element);
42+
do_copy = !do_copy;
43+
return do_copy;
44+
};
45+
benchmark::DoNotOptimize(c);
46+
benchmark::DoNotOptimize(out);
47+
auto result = copy_if(c.begin(), c.end(), out.begin(), pred);
48+
benchmark::DoNotOptimize(result);
49+
}
50+
})->Range(8, 1 << 20);
51+
};
52+
bm.operator()<std::vector<int>>("std::copy_if(vector<int>) (every other)", std_copy_if);
53+
bm.operator()<std::deque<int>>("std::copy_if(deque<int>) (every other)", std_copy_if);
54+
bm.operator()<std::list<int>>("std::copy_if(list<int>) (every other)", std_copy_if);
7555

76-
int main(int argc, char** argv) {
77-
auto std_copy_if = [](auto first, auto last, auto out, auto pred) { return std::copy_if(first, last, out, pred); };
78-
auto ranges_copy_if = std::ranges::copy_if;
56+
bm.operator()<std::vector<int>>("ranges::copy_if(vector<int>) (every other)", std::ranges::copy_if);
57+
bm.operator()<std::deque<int>>("ranges::copy_if(deque<int>) (every other)", std::ranges::copy_if);
58+
bm.operator()<std::list<int>>("ranges::copy_if(list<int>) (every other)", std::ranges::copy_if);
59+
}
7960

80-
// std::copy_if
81-
bm_copy_every_other_element<std::vector<int>>("std::copy_if(vector<int>) (every other)", std_copy_if);
82-
bm_copy_every_other_element<std::deque<int>>("std::copy_if(deque<int>) (every other)", std_copy_if);
83-
bm_copy_every_other_element<std::list<int>>("std::copy_if(list<int>) (every other)", std_copy_if);
61+
// Benchmark {std,ranges}::copy_if where we copy the full range.
62+
// Copy the full range.
63+
{
64+
auto bm = []<class Container>(std::string name, auto copy_if) {
65+
benchmark::RegisterBenchmark(name, [copy_if](auto& st) {
66+
std::size_t const n = st.range(0);
67+
using ValueType = typename Container::value_type;
68+
Container c;
69+
std::generate_n(std::back_inserter(c), n, [] { return Generate<ValueType>::random(); });
8470

85-
bm_copy_entire_range<std::vector<int>>("std::copy_if(vector<int>) (entire range)", std_copy_if);
86-
bm_copy_entire_range<std::deque<int>>("std::copy_if(deque<int>) (entire range)", std_copy_if);
87-
bm_copy_entire_range<std::list<int>>("std::copy_if(list<int>) (entire range)", std_copy_if);
71+
std::vector<ValueType> out(n);
8872

89-
// ranges::copy
90-
bm_copy_every_other_element<std::vector<int>>("ranges::copy_if(vector<int>) (every other)", ranges_copy_if);
91-
bm_copy_every_other_element<std::deque<int>>("ranges::copy_if(deque<int>) (every other)", ranges_copy_if);
92-
bm_copy_every_other_element<std::list<int>>("ranges::copy_if(list<int>) (every other)", ranges_copy_if);
73+
for ([[maybe_unused]] auto _ : st) {
74+
auto pred = [](auto& element) {
75+
benchmark::DoNotOptimize(element);
76+
return true;
77+
};
78+
benchmark::DoNotOptimize(c);
79+
benchmark::DoNotOptimize(out);
80+
auto result = copy_if(c.begin(), c.end(), out.begin(), pred);
81+
benchmark::DoNotOptimize(result);
82+
}
83+
})->Range(8, 1 << 20);
84+
};
85+
bm.operator()<std::vector<int>>("std::copy_if(vector<int>) (entire range)", std_copy_if);
86+
bm.operator()<std::deque<int>>("std::copy_if(deque<int>) (entire range)", std_copy_if);
87+
bm.operator()<std::list<int>>("std::copy_if(list<int>) (entire range)", std_copy_if);
9388

94-
bm_copy_entire_range<std::vector<int>>("ranges::copy_if(vector<int>) (entire range)", ranges_copy_if);
95-
bm_copy_entire_range<std::deque<int>>("ranges::copy_if(deque<int>) (entire range)", ranges_copy_if);
96-
bm_copy_entire_range<std::list<int>>("ranges::copy_if(list<int>) (entire range)", ranges_copy_if);
89+
bm.operator()<std::vector<int>>("ranges::copy_if(vector<int>) (entire range)", std::ranges::copy_if);
90+
bm.operator()<std::deque<int>>("ranges::copy_if(deque<int>) (entire range)", std::ranges::copy_if);
91+
bm.operator()<std::list<int>>("ranges::copy_if(list<int>) (entire range)", std::ranges::copy_if);
92+
}
9793

9894
benchmark::Initialize(&argc, argv);
9995
benchmark::RunSpecifiedBenchmarks();

0 commit comments

Comments
 (0)