Skip to content

Commit 457c405

Browse files
committed
Avoid invoking operator,
1 parent a5c98e2 commit 457c405

File tree

4 files changed

+85
-1
lines changed

4 files changed

+85
-1
lines changed

libcxx/include/__vector/vector.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ template <class _Iterator, class _Sentinel>
10181018
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
10191019
vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) {
10201020
pointer __cur = __begin_;
1021-
for (; __first != __last && __cur != __end_; ++__cur, ++__first)
1021+
for (; __first != __last && __cur != __end_; ++__first, (void)++__cur)
10221022
*__cur = *__first;
10231023
if (__cur != __end_)
10241024
__destruct_at_end(__cur);

libcxx/test/benchmarks/ContainerBenchmarks.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,76 @@ void BM_Assignment(benchmark::State& st, Container) {
4848
}
4949
}
5050

51+
// Wrap any Iterator into an input iterator
52+
template <typename Iterator>
53+
class InputIterator {
54+
using iter_traits = std::iterator_traits<Iterator>;
55+
56+
public:
57+
using iterator_category = std::input_iterator_tag;
58+
using value_type = typename iter_traits::value_type;
59+
using difference_type = typename iter_traits::difference_type;
60+
using pointer = typename iter_traits::pointer;
61+
using reference = typename iter_traits::reference;
62+
63+
InputIterator(Iterator it) : current_(it) {}
64+
65+
reference operator*() { return *current_; }
66+
InputIterator& operator++() {
67+
++current_;
68+
return *this;
69+
}
70+
InputIterator operator++(int) {
71+
InputIterator tmp = *this;
72+
++(*this);
73+
return tmp;
74+
}
75+
76+
friend bool operator==(const InputIterator& lhs, const InputIterator& rhs) { return lhs.current_ == rhs.current_; }
77+
friend bool operator!=(const InputIterator& lhs, const InputIterator& rhs) { return !(lhs == rhs); }
78+
79+
private:
80+
Iterator current_;
81+
};
82+
83+
template <typename Iterator>
84+
InputIterator<Iterator> make_input_iterator(Iterator it) {
85+
return InputIterator<Iterator>(it);
86+
}
87+
88+
template <class Container,
89+
class GenInputs,
90+
typename std::enable_if<std::is_trivial<typename Container::value_type>::value>::type* = nullptr>
91+
void BM_AssignInputIterIter(benchmark::State& st, Container c, GenInputs gen) {
92+
auto in = gen(st.range(1));
93+
benchmark::DoNotOptimize(&in);
94+
for (auto _ : st) {
95+
st.PauseTiming();
96+
c.resize(st.range(0));
97+
benchmark::DoNotOptimize(&c);
98+
st.ResumeTiming();
99+
c.assign(make_input_iterator(in.begin()), make_input_iterator(in.end()));
100+
benchmark::ClobberMemory();
101+
}
102+
}
103+
104+
template <class Container,
105+
class GenInputs,
106+
typename std::enable_if<!std::is_trivial<typename Container::value_type>::value>::type* = nullptr>
107+
void BM_AssignInputIterIter(benchmark::State& st, Container c, GenInputs gen) {
108+
auto v = gen(1, 100);
109+
auto in = gen(st.range(1), 32);
110+
benchmark::DoNotOptimize(&in);
111+
for (auto _ : st) {
112+
st.PauseTiming();
113+
c.resize(st.range(0), v[0]);
114+
benchmark::DoNotOptimize(&c);
115+
st.ResumeTiming();
116+
c.assign(make_input_iterator(in.begin()), make_input_iterator(in.end()));
117+
benchmark::ClobberMemory();
118+
}
119+
}
120+
51121
template <class Container>
52122
void BM_ConstructSizeValue(benchmark::State& st, Container, typename Container::value_type const& val) {
53123
const auto size = st.range(0);

libcxx/test/benchmarks/GenerateInput.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ inline std::vector<std::string> getRandomStringInputs(std::size_t N) {
116116
return inputs;
117117
}
118118

119+
inline std::vector<std::string> getRandomStringInputsWithLength(std::size_t N, std::size_t len) {
120+
std::vector<std::string> inputs;
121+
inputs.reserve(N);
122+
for (size_t i = 0; i < N; ++i)
123+
inputs.push_back(getRandomString(len));
124+
return inputs;
125+
}
126+
119127
inline std::vector<std::string> getPrefixedRandomStringInputs(std::size_t N) {
120128
std::vector<std::string> inputs;
121129
constexpr int kSuffixLength = 32;

libcxx/test/benchmarks/vector_operations.bench.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,10 @@ BENCHMARK(bm_grow<std::string>);
6969
BENCHMARK(bm_grow<std::unique_ptr<int>>);
7070
BENCHMARK(bm_grow<std::deque<int>>);
7171

72+
BENCHMARK_CAPTURE(BM_AssignInputIterIter, vector_int, std::vector<int>{}, getRandomIntegerInputs<int>)
73+
->Args({TestNumInputs, TestNumInputs});
74+
75+
BENCHMARK_CAPTURE(BM_AssignInputIterIter, vector_string, std::vector<std::string>{}, getRandomStringInputsWithLength)
76+
->Args({TestNumInputs, TestNumInputs});
77+
7278
BENCHMARK_MAIN();

0 commit comments

Comments
 (0)