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 = std::__type_identity_t <typename Container::iterator>>
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,26 @@ 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 = std:: __type_identity_t < typename Container::iterator> >
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));
136
+ // Range rg(in.begin(), in.end());
92
137
while (st.KeepRunning ()) {
93
- Container c (std::from_range, in);
138
+ Container c (std::from_range, rg); // we assume the destructor doesn't dominate the benchmark
94
139
DoNotOptimizeData (c);
95
140
}
96
141
}
@@ -108,6 +153,52 @@ void BM_Pushback_no_grow(benchmark::State& state, Container c) {
108
153
}
109
154
}
110
155
156
+ template <class Container , class GenInputs , class InputIter = std::__type_identity_t <typename Container::iterator>>
157
+ void BM_InsertIterIterIter (benchmark::State& st, GenInputs gen, InputIter = {}) {
158
+ auto in = gen (st.range (0 ));
159
+ DoNotOptimizeData (in);
160
+ const auto beg = InputIter (in.begin ());
161
+ const auto end = InputIter (in.end ());
162
+ const unsigned size = 100 ;
163
+ Container c (size);
164
+ DoNotOptimizeData (c);
165
+ for (auto _ : st) {
166
+ c.insert (c.begin (), beg, end);
167
+ DoNotOptimizeData (c);
168
+ c.erase (c.begin () + size, c.end ()); // avoid growing indefinitely
169
+ }
170
+ }
171
+
172
+ template <class Container , class GenInputs , class Range = std::__type_identity_t <Container>>
173
+ void BM_InsertRange (benchmark::State& st, GenInputs gen, Range = {}) {
174
+ auto in = gen (st.range (0 ));
175
+ DoNotOptimizeData (in);
176
+ Range rg (std::ranges::begin (in), std::ranges::end (in));
177
+ const unsigned size = 100 ;
178
+ Container c (size);
179
+ DoNotOptimizeData (c);
180
+ for (auto _ : st) {
181
+ c.insert_range (c.begin (), rg);
182
+ DoNotOptimizeData (c);
183
+ c.erase (c.begin () + size, c.end ()); // avoid growing indefinitely
184
+ }
185
+ }
186
+
187
+ template <class Container , class GenInputs , class Range = std::__type_identity_t <Container>>
188
+ void BM_AppendRange (benchmark::State& st, GenInputs gen, Range = {}) {
189
+ auto in = gen (st.range (0 ));
190
+ DoNotOptimizeData (in);
191
+ Range rg (std::ranges::begin (in), std::ranges::end (in));
192
+ const unsigned size = 100 ;
193
+ Container c (size);
194
+ DoNotOptimizeData (c);
195
+ for (auto _ : st) {
196
+ c.append_range (rg);
197
+ DoNotOptimizeData (c);
198
+ c.erase (c.begin () + size, c.end ()); // avoid growing indefinitely
199
+ }
200
+ }
201
+
111
202
template <class Container , class GenInputs >
112
203
void BM_InsertValue (benchmark::State& st, Container c, GenInputs gen) {
113
204
auto in = gen (st.range (0 ));
0 commit comments