10
10
#ifndef BENCHMARK_CONTAINER_BENCHMARKS_H
11
11
#define BENCHMARK_CONTAINER_BENCHMARKS_H
12
12
13
+ #include < __type_traits/type_identity.h>
13
14
#include < cassert>
14
15
#include < iterator>
15
16
#include < utility>
16
17
17
18
#include " benchmark/benchmark.h"
19
+ #include " ../../std/containers/from_range_helpers.h"
18
20
#include " ../Utilities.h"
19
21
#include " test_iterators.h"
20
22
@@ -51,16 +53,57 @@ void BM_Assignment(benchmark::State& st, Container) {
51
53
}
52
54
}
53
55
56
+ template <class Container , class Generator , class InputIter = decltype(std::declval<Generator>()(0 ).begin())>
57
+ void BM_AssignIterIter (benchmark::State& st, Generator gen, InputIter = {}) {
58
+ using T = typename Container::value_type;
59
+ auto size = st.range (0 );
60
+ auto in1 = gen (size);
61
+ auto in2 = gen (size);
62
+ DoNotOptimizeData (in1);
63
+ DoNotOptimizeData (in2);
64
+ Container c (in1.begin (), in1.end ());
65
+ DoNotOptimizeData (c);
66
+ bool toggle = false ;
67
+ for (auto _ : st) {
68
+ std::vector<T>& in = toggle ? in1 : in2;
69
+ auto first = in.begin ();
70
+ auto last = in.end ();
71
+ c.assign (InputIter (first), InputIter (last));
72
+ toggle = !toggle;
73
+ DoNotOptimizeData (c);
74
+ }
75
+ }
76
+
77
+ template <typename Container, class Generator , class Range = std::__type_identity_t <Container>>
78
+ void BM_AssignRange (benchmark::State& st, Generator gen, Range = {}) {
79
+ auto size = st.range (0 );
80
+ auto in1 = gen (size);
81
+ auto in2 = gen (size);
82
+ DoNotOptimizeData (in1);
83
+ DoNotOptimizeData (in2);
84
+ Range rg1 (std::ranges::begin (in1), std::ranges::end (in1));
85
+ Range rg2 (std::ranges::begin (in2), std::ranges::end (in2));
86
+ Container c (std::from_range, rg1);
87
+ DoNotOptimizeData (c);
88
+ bool toggle = false ;
89
+ for (auto _ : st) {
90
+ auto & rg = toggle ? rg1 : rg2;
91
+ c.assign_range (rg);
92
+ toggle = !toggle;
93
+ DoNotOptimizeData (c);
94
+ }
95
+ }
96
+
54
97
template <std::size_t ... sz, typename Container, typename GenInputs>
55
98
void BM_AssignInputIterIter (benchmark::State& st, Container c, GenInputs gen) {
56
99
auto v = gen (1 , sz...);
57
100
c.resize (st.range (0 ), v[0 ]);
58
101
auto in = gen (st.range (1 ), sz...);
59
- benchmark::DoNotOptimize (& in);
60
- benchmark::DoNotOptimize (& c);
102
+ DoNotOptimizeData ( in);
103
+ DoNotOptimizeData ( c);
61
104
for (auto _ : st) {
62
105
c.assign (cpp17_input_iterator (in.begin ()), cpp17_input_iterator (in.end ()));
63
- benchmark::ClobberMemory ( );
106
+ DoNotOptimizeData (c );
64
107
}
65
108
}
66
109
@@ -73,24 +116,25 @@ void BM_ConstructSizeValue(benchmark::State& st, Container, typename Container::
73
116
}
74
117
}
75
118
76
- template <class Container , class GenInputs >
77
- void BM_ConstructIterIter (benchmark::State& st, Container, GenInputs gen) {
78
- auto in = gen (st.range (0 ));
79
- const auto begin = in. begin ( );
80
- const auto end = in.end ( );
81
- benchmark::DoNotOptimize (&in );
119
+ template <class Container , class GenInputs , class InputIter = decltype(std::declval<GenInputs>()( 0 ).begin()) >
120
+ void BM_ConstructIterIter (benchmark::State& st, GenInputs gen, InputIter = {} ) {
121
+ auto in = gen (st.range (0 ));
122
+ DoNotOptimizeData (in );
123
+ const auto begin = InputIter ( in.begin () );
124
+ const auto end = InputIter (in. end () );
82
125
while (st.KeepRunning ()) {
83
- Container c (begin, end);
126
+ Container c (begin, end); // we assume the destructor doesn't dominate the benchmark
84
127
DoNotOptimizeData (c);
85
128
}
86
129
}
87
130
88
- template <class Container , class GenInputs >
89
- void BM_ConstructFromRange (benchmark::State& st, Container, GenInputs gen) {
131
+ template <class Container , class GenInputs , class Range = std:: __type_identity_t <Container> >
132
+ void BM_ConstructFromRange (benchmark::State& st, GenInputs gen, Range = {} ) {
90
133
auto in = gen (st.range (0 ));
91
- benchmark::DoNotOptimize (&in);
134
+ DoNotOptimizeData (in);
135
+ Range rg (std::ranges::begin (in), std::ranges::end (in));
92
136
while (st.KeepRunning ()) {
93
- Container c (std::from_range, in);
137
+ Container c (std::from_range, rg); // we assume the destructor doesn't dominate the benchmark
94
138
DoNotOptimizeData (c);
95
139
}
96
140
}
@@ -108,6 +152,52 @@ void BM_Pushback_no_grow(benchmark::State& state, Container c) {
108
152
}
109
153
}
110
154
155
+ template <class Container , class GenInputs , class InputIter = decltype(std::declval<GenInputs>()(0 ).begin())>
156
+ void BM_InsertIterIterIter (benchmark::State& st, GenInputs gen, InputIter = {}) {
157
+ auto in = gen (st.range (0 ));
158
+ DoNotOptimizeData (in);
159
+ const auto beg = InputIter (in.begin ());
160
+ const auto end = InputIter (in.end ());
161
+ const unsigned size = 100 ;
162
+ Container c (size);
163
+ DoNotOptimizeData (c);
164
+ for (auto _ : st) {
165
+ c.insert (c.begin (), beg, end);
166
+ DoNotOptimizeData (c);
167
+ c.erase (c.begin () + size, c.end ()); // avoid growing indefinitely
168
+ }
169
+ }
170
+
171
+ template <class Container , class GenInputs , class Range = std::__type_identity_t <Container>>
172
+ void BM_InsertRange (benchmark::State& st, GenInputs gen, Range = {}) {
173
+ auto in = gen (st.range (0 ));
174
+ DoNotOptimizeData (in);
175
+ Range rg (std::ranges::begin (in), std::ranges::end (in));
176
+ const unsigned size = 100 ;
177
+ Container c (size);
178
+ DoNotOptimizeData (c);
179
+ for (auto _ : st) {
180
+ c.insert_range (c.begin (), rg);
181
+ DoNotOptimizeData (c);
182
+ c.erase (c.begin () + size, c.end ()); // avoid growing indefinitely
183
+ }
184
+ }
185
+
186
+ template <class Container , class GenInputs , class Range = std::__type_identity_t <Container>>
187
+ void BM_AppendRange (benchmark::State& st, GenInputs gen, Range = {}) {
188
+ auto in = gen (st.range (0 ));
189
+ DoNotOptimizeData (in);
190
+ Range rg (std::ranges::begin (in), std::ranges::end (in));
191
+ const unsigned size = 100 ;
192
+ Container c (size);
193
+ DoNotOptimizeData (c);
194
+ for (auto _ : st) {
195
+ c.append_range (rg);
196
+ DoNotOptimizeData (c);
197
+ c.erase (c.begin () + size, c.end ()); // avoid growing indefinitely
198
+ }
199
+ }
200
+
111
201
template <class Container , class GenInputs >
112
202
void BM_InsertValue (benchmark::State& st, Container c, GenInputs gen) {
113
203
auto in = gen (st.range (0 ));
0 commit comments