10
10
11
11
#include < algorithm>
12
12
#include < cassert>
13
+ #include < cstddef>
13
14
#include < deque>
14
15
#include < iterator>
15
16
#include < list>
@@ -26,66 +27,66 @@ auto compute_median(auto first, auto last) {
26
27
return *middle;
27
28
}
28
29
29
- template <class Container , bool Partitioned, class Operation >
30
- void bm (std::string operation_name, Operation is_partitioned) {
31
- auto bench = [is_partitioned](auto & st) {
32
- auto const size = st.range (0 );
33
- using ValueType = typename Container::value_type;
34
- Container c;
35
- std::generate_n (std::back_inserter (c), size, [] { return Generate<ValueType>::random (); });
36
-
37
- // Partition the container in two equally-sized halves, ensuring the median
38
- // value appears in the left half. Note that the median value isn't located
39
- // in the middle -- this isn't std::nth_element.
40
- ValueType median = compute_median (c.begin (), c.end ());
41
- auto pred = [median](auto const & element) { return element <= median; };
42
- std::partition (c.begin (), c.end (), pred);
43
- assert (std::is_partitioned (c.begin (), c.end (), pred));
44
-
45
- if constexpr (!Partitioned) {
46
- // De-partition the container by swapping the element containing the median
47
- // value with the last one.
48
- auto median_it = std::find (c.begin (), c.end (), median);
49
- auto last_it = std::next (c.begin (), c.size () - 1 );
50
- std::iter_swap (median_it, last_it);
51
- assert (!std::is_partitioned (c.begin (), c.end (), pred));
52
- }
53
-
54
- for ([[maybe_unused]] auto _ : st) {
55
- auto result = is_partitioned (c.begin (), c.end (), pred);
56
- benchmark::DoNotOptimize (result);
57
- benchmark::DoNotOptimize (c);
58
- benchmark::ClobberMemory ();
59
- }
60
- };
61
- benchmark::RegisterBenchmark (operation_name, bench)->Arg (32 )->Arg (1024 )->Arg (8192 );
62
- }
63
-
64
30
int main (int argc, char ** argv) {
65
- auto std_is_partitioned = [](auto first, auto last, auto pred) { return std::is_partitioned (first, last, pred); };
66
- auto ranges_is_partitioned = [](auto first, auto last, auto pred) {
67
- return std::ranges::is_partitioned (first, last, pred);
31
+ auto std_is_partitioned = [](auto first, auto last, auto pred) { return std::is_partitioned (first, last, pred); };
32
+
33
+ auto bm = []<class Container , bool Partitioned>(std::string name, auto is_partitioned) {
34
+ benchmark::RegisterBenchmark (
35
+ name,
36
+ [is_partitioned](auto & st) {
37
+ std::size_t const size = st.range (0 );
38
+ using ValueType = typename Container::value_type;
39
+ Container c;
40
+ std::generate_n (std::back_inserter (c), size, [] { return Generate<ValueType>::random (); });
41
+
42
+ // Partition the container in two equally-sized halves, ensuring the median
43
+ // value appears in the left half. Note that the median value isn't located
44
+ // in the middle -- this isn't std::nth_element.
45
+ ValueType median = compute_median (c.begin (), c.end ());
46
+ auto pred = [median](auto const & element) { return element <= median; };
47
+ std::partition (c.begin (), c.end (), pred);
48
+ assert (std::is_partitioned (c.begin (), c.end (), pred));
49
+
50
+ if constexpr (!Partitioned) {
51
+ // De-partition the container by swapping the element containing the median
52
+ // value with the last one.
53
+ auto median_it = std::find (c.begin (), c.end (), median);
54
+ auto last_it = std::next (c.begin (), c.size () - 1 );
55
+ std::iter_swap (median_it, last_it);
56
+ assert (!std::is_partitioned (c.begin (), c.end (), pred));
57
+ }
58
+
59
+ for ([[maybe_unused]] auto _ : st) {
60
+ benchmark::DoNotOptimize (c);
61
+ auto result = is_partitioned (c.begin (), c.end (), pred);
62
+ benchmark::DoNotOptimize (result);
63
+ }
64
+ })
65
+ ->Arg (32 )
66
+ ->Arg (1024 )
67
+ ->Arg (8192 );
68
68
};
69
69
70
70
// std::is_partitioned
71
- bm<std::vector<int >, true >(" std::is_partitioned(vector<int>) (partitioned)" , std_is_partitioned);
72
- bm<std::vector<int >, false >(" std::is_partitioned(vector<int>) (not partitioned )" , std_is_partitioned);
71
+ bm. operator () <std::vector<int >, true >(" std::is_partitioned(vector<int>) (partitioned)" , std_is_partitioned);
72
+ bm. operator () <std::vector<int >, false >(" std::is_partitioned(vector<int>) (unpartitioned )" , std_is_partitioned);
73
73
74
- bm<std::deque<int >, true >(" std::is_partitioned(deque<int>) (partitioned)" , std_is_partitioned);
75
- bm<std::deque<int >, false >(" std::is_partitioned(deque<int>) (not partitioned )" , std_is_partitioned);
74
+ bm. operator () <std::deque<int >, true >(" std::is_partitioned(deque<int>) (partitioned)" , std_is_partitioned);
75
+ bm. operator () <std::deque<int >, false >(" std::is_partitioned(deque<int>) (unpartitioned )" , std_is_partitioned);
76
76
77
- bm<std::list<int >, true >(" std::is_partitioned(list<int>) (partitioned)" , std_is_partitioned);
78
- bm<std::list<int >, false >(" std::is_partitioned(list<int>) (not partitioned )" , std_is_partitioned);
77
+ bm. operator () <std::list<int >, true >(" std::is_partitioned(list<int>) (partitioned)" , std_is_partitioned);
78
+ bm. operator () <std::list<int >, false >(" std::is_partitioned(list<int>) (unpartitioned )" , std_is_partitioned);
79
79
80
80
// ranges::is_partitioned
81
- bm<std::vector<int >, true >(" ranges::is_partitioned(vector<int>) (partitioned)" , ranges_is_partitioned);
82
- bm<std::vector<int >, false >(" ranges::is_partitioned(vector<int>) (not partitioned)" , ranges_is_partitioned);
81
+ bm.operator ()<std::vector<int >, true >(" rng::is_partitioned(vector<int>) (partitioned)" , std::ranges::is_partitioned);
82
+ bm.operator ()<std::vector<int >, false >(
83
+ " rng::is_partitioned(vector<int>) (unpartitioned)" , std::ranges::is_partitioned);
83
84
84
- bm<std::deque<int >, true >(" ranges ::is_partitioned(deque<int>) (partitioned)" , ranges_is_partitioned );
85
- bm<std::deque<int >, false >(" ranges ::is_partitioned(deque<int>) (not partitioned )" , ranges_is_partitioned );
85
+ bm. operator () <std::deque<int >, true >(" rng ::is_partitioned(deque<int>) (partitioned)" , std::ranges::is_partitioned );
86
+ bm. operator () <std::deque<int >, false >(" rng ::is_partitioned(deque<int>) (unpartitioned )" , std::ranges::is_partitioned );
86
87
87
- bm<std::list<int >, true >(" ranges ::is_partitioned(list<int>) (partitioned)" , ranges_is_partitioned );
88
- bm<std::list<int >, false >(" ranges ::is_partitioned(list<int>) (not partitioned )" , ranges_is_partitioned );
88
+ bm. operator () <std::list<int >, true >(" rng ::is_partitioned(list<int>) (partitioned)" , std::ranges::is_partitioned );
89
+ bm. operator () <std::list<int >, false >(" rng ::is_partitioned(list<int>) (unpartitioned )" , std::ranges::is_partitioned );
89
90
90
91
benchmark::Initialize (&argc, argv);
91
92
benchmark::RunSpecifiedBenchmarks ();
0 commit comments