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 = 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+
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,26 @@ 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 = 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 () );
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));
136+ // Range rg(in.begin(), in.end());
92137 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
94139 DoNotOptimizeData (c);
95140 }
96141}
@@ -108,6 +153,52 @@ void BM_Pushback_no_grow(benchmark::State& state, Container c) {
108153 }
109154}
110155
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+
111202template <class Container , class GenInputs >
112203void BM_InsertValue (benchmark::State& st, Container c, GenInputs gen) {
113204 auto in = gen (st.range (0 ));
0 commit comments