Skip to content

Commit a31c874

Browse files
committed
Add benchmark tests
1 parent ae7a50e commit a31c874

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

libcxx/test/benchmarks/ContainerBenchmarks.h

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,90 @@ void BM_InsertValueRehash(benchmark::State& st, Container c, GenInputs gen) {
119119
}
120120
}
121121

122+
// Wrap any Iterator into an input iterator
123+
template <typename Iterator>
124+
class InputIterator {
125+
using iter_traits = std::iterator_traits<Iterator>;
126+
127+
public:
128+
using iterator_category = std::input_iterator_tag;
129+
using value_type = typename iter_traits::value_type;
130+
using difference_type = typename iter_traits::difference_type;
131+
using pointer = typename iter_traits::pointer;
132+
using reference = typename iter_traits::reference;
133+
134+
InputIterator(Iterator it) : current_(it) {}
135+
136+
reference operator*() { return *current_; }
137+
InputIterator& operator++() {
138+
++current_;
139+
return *this;
140+
}
141+
InputIterator operator++(int) {
142+
InputIterator tmp = *this;
143+
++(*this);
144+
return tmp;
145+
}
146+
147+
friend bool operator==(const InputIterator& lhs, const InputIterator& rhs) { return lhs.current_ == rhs.current_; }
148+
friend bool operator!=(const InputIterator& lhs, const InputIterator& rhs) { return !(lhs == rhs); }
149+
150+
private:
151+
Iterator current_;
152+
};
153+
154+
template <typename Iterator>
155+
InputIterator<Iterator> make_input_iterator(Iterator it) {
156+
return InputIterator<Iterator>(it);
157+
}
158+
159+
// Test case: vector is empty
160+
template <class Container, class GenInputs>
161+
void BM_InsertIterInputIterIterEmpty(benchmark::State& st, Container _, GenInputs gen) {
162+
auto in = gen(st.range(0));
163+
benchmark::DoNotOptimize(&in);
164+
for (auto _ : st) {
165+
Container c;
166+
benchmark::DoNotOptimize(&c);
167+
benchmark::DoNotOptimize(c.insert(c.begin(), make_input_iterator(in.begin()), make_input_iterator(in.end())));
168+
benchmark::ClobberMemory();
169+
}
170+
}
171+
172+
// Test case: vector is half full
173+
template <class Container, class GenInputs>
174+
void BM_InsertIterInputIterIterHalfFull(benchmark::State& st, Container c, GenInputs gen) {
175+
for (auto _ : st) {
176+
st.PauseTiming();
177+
c = gen(st.range(0));
178+
c.reserve(c.size() * 2);
179+
auto in = gen(c.size() + 10);
180+
benchmark::DoNotOptimize(&c);
181+
benchmark::DoNotOptimize(&in);
182+
st.ResumeTiming();
183+
184+
benchmark::DoNotOptimize(c.insert(c.begin(), make_input_iterator(in.begin()), make_input_iterator(in.end())));
185+
benchmark::ClobberMemory();
186+
}
187+
}
188+
189+
// Test case: vector is almost full
190+
template <class Container, class GenInputs>
191+
void BM_InsertIterInputIterIterFull(benchmark::State& st, Container c, GenInputs gen) {
192+
for (auto _ : st) {
193+
st.PauseTiming();
194+
c = gen(st.range(0));
195+
c.reserve(c.size() + 5);
196+
auto in = gen(10);
197+
benchmark::DoNotOptimize(&c);
198+
benchmark::DoNotOptimize(&in);
199+
st.ResumeTiming();
200+
201+
benchmark::DoNotOptimize(c.insert(c.begin(), make_input_iterator(in.begin()), make_input_iterator(in.end())));
202+
benchmark::ClobberMemory();
203+
}
204+
}
205+
122206
template <class Container, class GenInputs>
123207
void BM_InsertDuplicate(benchmark::State& st, Container c, GenInputs gen) {
124208
auto in = gen(st.range(0));

libcxx/test/benchmarks/GenerateInput.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ inline std::vector<std::string> getRandomStringInputs(size_t N) {
119119
return inputs;
120120
}
121121

122+
inline std::vector<std::string> getShortRandomStringInputs(size_t N) {
123+
std::vector<std::string> inputs;
124+
for (size_t i = 0; i < N; ++i)
125+
inputs.push_back(getRandomString(10)); // SSO
126+
return inputs;
127+
}
128+
122129
inline std::vector<std::string> getPrefixedRandomStringInputs(size_t N) {
123130
std::vector<std::string> inputs;
124131
constexpr int kSuffixLength = 32;

libcxx/test/benchmarks/vector_operations.bench.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,20 @@ BENCHMARK(bm_grow<std::string>);
6767
BENCHMARK(bm_grow<std::unique_ptr<int>>);
6868
BENCHMARK(bm_grow<std::deque<int>>);
6969

70+
BENCHMARK_CAPTURE(BM_InsertIterInputIterIterEmpty, vector_int, std::vector<int>{}, getRandomIntegerInputs<int>)
71+
->Arg(TestNumInputs);
72+
BENCHMARK_CAPTURE(BM_InsertIterInputIterIterHalfFull, vector_int, std::vector<int>{}, getRandomIntegerInputs<int>)
73+
->Arg(TestNumInputs);
74+
BENCHMARK_CAPTURE(BM_InsertIterInputIterIterFull, vector_int, std::vector<int>{}, getRandomIntegerInputs<int>)
75+
->Arg(TestNumInputs);
76+
77+
BENCHMARK_CAPTURE(
78+
BM_InsertIterInputIterIterEmpty, vector_string, std::vector<std::string>{}, getShortRandomStringInputs)
79+
->Arg(TestNumInputs);
80+
BENCHMARK_CAPTURE(
81+
BM_InsertIterInputIterIterHalfFull, vector_string, std::vector<std::string>{}, getShortRandomStringInputs)
82+
->Arg(TestNumInputs);
83+
BENCHMARK_CAPTURE(BM_InsertIterInputIterIterFull, vector_string, std::vector<std::string>{}, getShortRandomStringInputs)
84+
->Arg(TestNumInputs);
85+
7086
BENCHMARK_MAIN();

0 commit comments

Comments
 (0)