18 #include "benchmark/benchmark.h" 26 void BM_InlinedVectorFill(benchmark::State& state) {
29 for (
auto _ : state) {
30 benchmark::DoNotOptimize(v);
34 BENCHMARK(BM_InlinedVectorFill)->Range(0, 1024);
36 void BM_InlinedVectorFillRange(benchmark::State& state) {
37 const int len = state.range(0);
38 std::unique_ptr<int[]> ia(
new int[len]);
39 for (
int i = 0;
i <
len;
i++) {
42 auto*
from = ia.get();
44 for (
auto _ : state) {
45 benchmark::DoNotOptimize(
from);
46 benchmark::DoNotOptimize(
to);
48 benchmark::DoNotOptimize(v);
51 BENCHMARK(BM_InlinedVectorFillRange)->Range(0, 1024);
53 void BM_StdVectorFill(benchmark::State& state) {
56 for (
auto _ : state) {
57 benchmark::DoNotOptimize(v);
58 benchmark::DoNotOptimize(val);
62 BENCHMARK(BM_StdVectorFill)->Range(0, 1024);
68 bool StringRepresentedInline(std::string s) {
69 const char* chars = s.data();
71 return s1.data() != chars;
74 int GetNonShortStringOptimizationSize() {
75 for (
int i = 24;
i <= 192;
i *= 2) {
76 if (!StringRepresentedInline(std::string(
i,
'A'))) {
82 "Failed to find a std::string larger than the short std::string optimization");
86 void BM_InlinedVectorFillString(benchmark::State& state) {
87 const int len = state.range(0);
88 const int no_sso = GetNonShortStringOptimizationSize();
89 std::string strings[4] = {std::string(no_sso,
'A'), std::string(no_sso,
'B'),
90 std::string(no_sso,
'C'), std::string(no_sso,
'D')};
92 for (
auto _ : state) {
94 for (
int i = 0;
i <
len;
i++) {
98 state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len);
100 BENCHMARK(BM_InlinedVectorFillString)->Range(0, 1024);
102 void BM_StdVectorFillString(benchmark::State& state) {
103 const int len = state.range(0);
104 const int no_sso = GetNonShortStringOptimizationSize();
105 std::string strings[4] = {std::string(no_sso,
'A'), std::string(no_sso,
'B'),
106 std::string(no_sso,
'C'), std::string(no_sso,
'D')};
108 for (
auto _ : state) {
109 std::vector<std::string>
v;
110 for (
int i = 0;
i <
len;
i++) {
111 v.push_back(strings[
i & 3]);
114 state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len);
116 BENCHMARK(BM_StdVectorFillString)->Range(0, 1024);
125 void BM_InlinedVectorAssignments(benchmark::State& state) {
126 const int len = state.range(0);
133 for (
auto _ : state) {
134 benchmark::DoNotOptimize(dst);
135 benchmark::DoNotOptimize(src);
139 BENCHMARK(BM_InlinedVectorAssignments)
147 void BM_CreateFromContainer(benchmark::State& state) {
148 for (
auto _ : state) {
150 benchmark::DoNotOptimize(src);
152 benchmark::DoNotOptimize(dst);
155 BENCHMARK(BM_CreateFromContainer);
157 struct LargeCopyableOnly {
158 LargeCopyableOnly() : d(1024, 17) {}
159 LargeCopyableOnly(
const LargeCopyableOnly&
o) =
default;
160 LargeCopyableOnly& operator=(
const LargeCopyableOnly&
o) =
default;
165 struct LargeCopyableSwappable {
166 LargeCopyableSwappable() : d(1024, 17) {}
168 LargeCopyableSwappable(
const LargeCopyableSwappable&
o) =
default;
170 LargeCopyableSwappable& operator=(LargeCopyableSwappable
o) {
176 friend void swap(LargeCopyableSwappable&
a, LargeCopyableSwappable&
b) {
184 struct LargeCopyableMovable {
185 LargeCopyableMovable() : d(1024, 17) {}
191 struct LargeCopyableMovableSwappable {
192 LargeCopyableMovableSwappable() : d(1024, 17) {}
193 LargeCopyableMovableSwappable(
const LargeCopyableMovableSwappable&
o) =
195 LargeCopyableMovableSwappable(LargeCopyableMovableSwappable&&
o) =
default;
197 LargeCopyableMovableSwappable& operator=(LargeCopyableMovableSwappable
o) {
202 LargeCopyableMovableSwappable& operator=(LargeCopyableMovableSwappable&&
o) =
205 friend void swap(LargeCopyableMovableSwappable&
a,
206 LargeCopyableMovableSwappable&
b) {
214 template <
typename ElementType>
215 void BM_SwapElements(benchmark::State& state) {
216 const int len = state.range(0);
220 for (
auto _ : state) {
222 benchmark::DoNotOptimize(
a);
223 benchmark::DoNotOptimize(b);
227 BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableOnly)->Range(0, 1024);
228 BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableSwappable)->Range(0, 1024);
229 BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableMovable)->Range(0, 1024);
230 BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableMovableSwappable)
237 template <
typename VecType>
238 void BM_Sizeof(benchmark::State& state) {
240 for (
auto _ : state) {
266 void BM_InlinedVectorIndexInlined(benchmark::State& state) {
268 for (
auto _ : state) {
269 benchmark::DoNotOptimize(v);
270 benchmark::DoNotOptimize(v[4]);
273 BENCHMARK(BM_InlinedVectorIndexInlined);
275 void BM_InlinedVectorIndexExternal(benchmark::State& state) {
276 absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
277 for (
auto _ : state) {
278 benchmark::DoNotOptimize(v);
279 benchmark::DoNotOptimize(v[4]);
282 BENCHMARK(BM_InlinedVectorIndexExternal);
284 void BM_StdVectorIndex(benchmark::State& state) {
285 std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
286 for (
auto _ : state) {
287 benchmark::DoNotOptimize(v);
288 benchmark::DoNotOptimize(v[4]);
291 BENCHMARK(BM_StdVectorIndex);
293 void BM_InlinedVectorDataInlined(benchmark::State& state) {
295 for (
auto _ : state) {
296 benchmark::DoNotOptimize(v);
297 benchmark::DoNotOptimize(v.
data());
300 BENCHMARK(BM_InlinedVectorDataInlined);
302 void BM_InlinedVectorDataExternal(benchmark::State& state) {
303 absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
304 for (
auto _ : state) {
305 benchmark::DoNotOptimize(v);
306 benchmark::DoNotOptimize(v.
data());
308 state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
310 BENCHMARK(BM_InlinedVectorDataExternal);
312 void BM_StdVectorData(benchmark::State& state) {
313 std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
314 for (
auto _ : state) {
315 benchmark::DoNotOptimize(v);
316 benchmark::DoNotOptimize(v.data());
318 state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
320 BENCHMARK(BM_StdVectorData);
322 void BM_InlinedVectorSizeInlined(benchmark::State& state) {
324 for (
auto _ : state) {
325 benchmark::DoNotOptimize(v);
326 benchmark::DoNotOptimize(v.
size());
329 BENCHMARK(BM_InlinedVectorSizeInlined);
331 void BM_InlinedVectorSizeExternal(benchmark::State& state) {
332 absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
333 for (
auto _ : state) {
334 benchmark::DoNotOptimize(v);
335 benchmark::DoNotOptimize(v.
size());
338 BENCHMARK(BM_InlinedVectorSizeExternal);
340 void BM_StdVectorSize(benchmark::State& state) {
341 std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
342 for (
auto _ : state) {
343 benchmark::DoNotOptimize(v);
344 benchmark::DoNotOptimize(v.size());
347 BENCHMARK(BM_StdVectorSize);
349 void BM_InlinedVectorEmptyInlined(benchmark::State& state) {
351 for (
auto _ : state) {
352 benchmark::DoNotOptimize(v);
353 benchmark::DoNotOptimize(v.
empty());
356 BENCHMARK(BM_InlinedVectorEmptyInlined);
358 void BM_InlinedVectorEmptyExternal(benchmark::State& state) {
359 absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
360 for (
auto _ : state) {
361 benchmark::DoNotOptimize(v);
362 benchmark::DoNotOptimize(v.
empty());
365 BENCHMARK(BM_InlinedVectorEmptyExternal);
367 void BM_StdVectorEmpty(benchmark::State& state) {
368 std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
369 for (
auto _ : state) {
370 benchmark::DoNotOptimize(v);
371 benchmark::DoNotOptimize(v.empty());
374 BENCHMARK(BM_StdVectorEmpty);
376 constexpr
size_t kInlineElements = 4;
377 constexpr
size_t kSmallSize = kInlineElements / 2;
378 constexpr
size_t kLargeSize = kInlineElements * 2;
379 constexpr
size_t kBatchSize = 100;
387 class NontrivialType {
392 : val_(other.val_) {}
395 const NontrivialType& other) {
408 template <
typename VecT,
typename PrepareVec,
typename TestVec>
409 void BatchedBenchmark(benchmark::State& state, PrepareVec prepare_vec,
411 VecT vectors[kBatchSize];
413 while (state.KeepRunningBatch(kBatchSize)) {
416 for (
auto& vec : vectors) {
419 benchmark::DoNotOptimize(vectors);
420 state.ResumeTiming();
423 for (
auto& vec : vectors) {
429 template <
typename VecT,
size_t FromSize>
430 void BM_Clear(benchmark::State& state) {
431 BatchedBenchmark<VecT>(
433 [](VecT* vec) { vec->resize(FromSize); },
434 [](VecT* vec) { vec->clear(); });
437 BENCHMARK_TEMPLATE(BM_Clear, TrivialVec, kSmallSize);
438 BENCHMARK_TEMPLATE(BM_Clear, TrivialVec, kLargeSize);
440 BENCHMARK_TEMPLATE(BM_Clear, NontrivialVec, kSmallSize);
441 BENCHMARK_TEMPLATE(BM_Clear, NontrivialVec, kLargeSize);
#define ABSL_RAW_LOG(severity,...)
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
size_type size() const noexcept
void swap(absl::InlinedVector< T, N, A > &a, absl::InlinedVector< T, N, A > &b) noexcept(noexcept(a.swap(b)))
#define ABSL_ATTRIBUTE_NOINLINE
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
bool empty() const noexcept
void push_back(const_reference v)