1010#ifndef BENCHMARK_CONTAINER_BENCHMARKS_H
1111#define BENCHMARK_CONTAINER_BENCHMARKS_H
1212
13+ #include < __type_traits/type_identity.h>
1314#include < cassert>
1415#include < iterator>
1516#include < utility>
1617
1718#include " benchmark/benchmark.h"
19+ #include " ../../std/containers/from_range_helpers.h"
1820#include " ../Utilities.h"
1921#include " test_iterators.h"
2022
@@ -51,16 +53,57 @@ void BM_Assignment(benchmark::State& st, Container) {
5153 }
5254}
5355
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+
5497template <std::size_t ... sz, typename Container, typename GenInputs>
5598void BM_AssignInputIterIter (benchmark::State& st, Container c, GenInputs gen) {
5699 auto v = gen (1 , sz...);
57100 c.resize (st.range (0 ), v[0 ]);
58101 auto in = gen (st.range (1 ), sz...);
59- benchmark::DoNotOptimize (& in);
60- benchmark::DoNotOptimize (& c);
102+ DoNotOptimizeData ( in);
103+ DoNotOptimizeData ( c);
61104 for (auto _ : st) {
62105 c.assign (cpp17_input_iterator (in.begin ()), cpp17_input_iterator (in.end ()));
63- benchmark::ClobberMemory ( );
106+ DoNotOptimizeData (c );
64107 }
65108}
66109
@@ -73,24 +116,25 @@ void BM_ConstructSizeValue(benchmark::State& st, Container, typename Container::
73116 }
74117}
75118
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 () );
82125 while (st.KeepRunning ()) {
83- Container c (begin, end);
126+ Container c (begin, end); // we assume the destructor doesn't dominate the benchmark
84127 DoNotOptimizeData (c);
85128 }
86129}
87130
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 = {} ) {
90133 auto in = gen (st.range (0 ));
91- benchmark::DoNotOptimize (&in);
134+ DoNotOptimizeData (in);
135+ Range rg (std::ranges::begin (in), std::ranges::end (in));
92136 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
94138 DoNotOptimizeData (c);
95139 }
96140}
@@ -108,6 +152,52 @@ void BM_Pushback_no_grow(benchmark::State& state, Container c) {
108152 }
109153}
110154
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+
111201template <class Container , class GenInputs >
112202void BM_InsertValue (benchmark::State& st, Container c, GenInputs gen) {
113203 auto in = gen (st.range (0 ));
0 commit comments