19 #include "benchmark/benchmark.h"
20 #include "absl/base/internal/raw_logging.h"
21 #include "absl/base/macros.h"
22 #include "absl/container/inlined_vector.h"
23 #include "absl/strings/str_cat.h"
33 for (
int i = 0;
i <
len; ++
i) {
39 BENCHMARK(BM_InlinedVectorFill)->Range(1, 256);
43 const std::vector<int> src(
len,
len);
48 v.assign(src.begin(), src.end());
52 BENCHMARK(BM_InlinedVectorFillRange)->Range(1, 256);
60 for (
int i = 0;
i <
len; ++
i) {
66 BENCHMARK(BM_StdVectorFill)->Range(1, 256);
73 const char* chars =
s.data();
75 return s1.data() != chars;
78 int GetNonShortStringOptimizationSize() {
79 for (
int i = 24;
i <= 192;
i *= 2) {
86 "Failed to find a string larger than the short string optimization");
92 const int no_sso = GetNonShortStringOptimizationSize();
98 for (
int i = 0;
i <
len;
i++) {
99 v.push_back(strings[
i & 3]);
104 BENCHMARK(BM_InlinedVectorFillString)->Range(0, 1024);
108 const int no_sso = GetNonShortStringOptimizationSize();
113 std::vector<std::string>
v;
114 for (
int i = 0;
i <
len;
i++) {
115 v.push_back(strings[
i & 3]);
120 BENCHMARK(BM_StdVectorFillString)->Range(0, 1024);
161 struct LargeCopyableOnly {
162 LargeCopyableOnly() :
d(1024, 17) {}
163 LargeCopyableOnly(
const LargeCopyableOnly&
o) =
default;
164 LargeCopyableOnly& operator=(
const LargeCopyableOnly&
o) =
default;
169 struct LargeCopyableSwappable {
170 LargeCopyableSwappable() :
d(1024, 17) {}
172 LargeCopyableSwappable(
const LargeCopyableSwappable&
o) =
default;
174 LargeCopyableSwappable& operator=(LargeCopyableSwappable
o) {
180 friend void swap(LargeCopyableSwappable&
a, LargeCopyableSwappable&
b) {
188 struct LargeCopyableMovable {
189 LargeCopyableMovable() :
d(1024, 17) {}
195 struct LargeCopyableMovableSwappable {
196 LargeCopyableMovableSwappable() :
d(1024, 17) {}
197 LargeCopyableMovableSwappable(
const LargeCopyableMovableSwappable&
o) =
199 LargeCopyableMovableSwappable(LargeCopyableMovableSwappable&&
o) =
default;
201 LargeCopyableMovableSwappable& operator=(LargeCopyableMovableSwappable
o) {
206 LargeCopyableMovableSwappable& operator=(LargeCopyableMovableSwappable&&
o) =
209 friend void swap(LargeCopyableMovableSwappable&
a,
210 LargeCopyableMovableSwappable&
b) {
218 template <
typename ElementType>
241 template <
typename VecType>
280 absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
286 BENCHMARK(BM_InlinedVectorIndexExternal);
289 std::vector<int>
v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
307 absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
317 std::vector<int>
v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
336 absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
345 std::vector<int>
v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
363 absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
369 BENCHMARK(BM_InlinedVectorEmptyExternal);
372 std::vector<int>
v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
380 constexpr
size_t kInlinedCapacity = 4;
381 constexpr
size_t kLargeSize = kInlinedCapacity * 2;
382 constexpr
size_t kSmallSize = kInlinedCapacity / 2;
383 constexpr
size_t kBatchSize = 100;
385 #define ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_FunctionTemplate, T) \
386 BENCHMARK_TEMPLATE(BM_FunctionTemplate, T, kLargeSize); \
387 BENCHMARK_TEMPLATE(BM_FunctionTemplate, T, kSmallSize)
389 #define ABSL_INTERNAL_BENCHMARK_TWO_SIZE(BM_FunctionTemplate, T) \
390 BENCHMARK_TEMPLATE(BM_FunctionTemplate, T, kLargeSize, kLargeSize); \
391 BENCHMARK_TEMPLATE(BM_FunctionTemplate, T, kLargeSize, kSmallSize); \
392 BENCHMARK_TEMPLATE(BM_FunctionTemplate, T, kSmallSize, kLargeSize); \
393 BENCHMARK_TEMPLATE(BM_FunctionTemplate, T, kSmallSize, kSmallSize)
395 template <
typename T>
402 class NontrivialType {
414 const NontrivialType& other) {
428 template <
typename T,
typename PrepareVecFn,
typename TestVecFn>
430 TestVecFn test_vec) {
431 std::array<InlVec<T>, kBatchSize> vector_batch{};
433 while (
state.KeepRunningBatch(kBatchSize)) {
436 for (
size_t i = 0;
i < kBatchSize; ++
i) {
437 prepare_vec(vector_batch.data() +
i,
i);
440 state.ResumeTiming();
443 for (
size_t i = 0;
i < kBatchSize; ++
i) {
444 test_vec(vector_batch.data() +
i,
i);
449 template <
typename T,
size_t ToSize>
451 using VecT = InlVec<T>;
455 [](InlVec<T>* vec,
size_t) { vec->~VecT(); },
457 [&](
void*
ptr, size_t) {
465 template <
typename T,
size_t ToSize>
467 using VecT = InlVec<T>;
472 [](InlVec<T>* vec,
size_t) { vec->~VecT(); },
474 [&](
void*
ptr, size_t) {
483 template <
typename T,
size_t ToSize>
485 using VecT = InlVec<T>;
486 std::array<T, ToSize> arr{};
489 [](InlVec<T>* vec,
size_t) { vec->~VecT(); },
491 [&](
void*
ptr, size_t) {
493 ::new (
ptr) VecT(arr.begin(), arr.end());
499 template <
typename T,
size_t ToSize>
501 using VecT = InlVec<T>;
502 VecT other_vec(ToSize);
506 [](InlVec<T>* vec,
size_t) { vec->~VecT(); },
508 [&](
void*
ptr, size_t) {
516 template <
typename T,
size_t ToSize>
518 using VecT = InlVec<T>;
519 std::array<VecT, kBatchSize> vector_batch{};
523 [&](InlVec<T>* vec,
size_t i) {
524 vector_batch[
i].clear();
525 vector_batch[
i].resize(ToSize);
529 [&](
void*
ptr,
size_t i) {
539 const int n =
state.range(0);
540 InlVec<int64_t> src(
n);
541 for (
auto s :
state) {
542 InlVec<int64_t>
copy(src);
546 BENCHMARK(BM_CopyTrivial)->Arg(0)->Arg(1)->Arg(kLargeSize);
550 const int n =
state.range(0);
551 InlVec<InlVec<int64_t>> src(
n);
552 for (
auto s :
state) {
553 InlVec<InlVec<int64_t>>
copy(src);
557 BENCHMARK(BM_CopyNonTrivial)->Arg(0)->Arg(1)->Arg(kLargeSize);
559 template <
typename T,
size_t FromSize,
size_t ToSize>
565 [](InlVec<T>* vec,
size_t) { vec->resize(FromSize); },
567 [&](InlVec<T>* vec, size_t) {
576 template <
typename T,
size_t FromSize,
size_t ToSize>
578 std::array<T, ToSize> arr{};
581 [](InlVec<T>* vec,
size_t) { vec->resize(FromSize); },
583 [&](InlVec<T>* vec, size_t) {
585 vec->assign(arr.begin(), arr.end());
591 template <
typename T,
size_t FromSize,
size_t ToSize>
593 InlVec<T> other_vec(ToSize);
596 [](InlVec<T>* vec,
size_t) { vec->resize(FromSize); },
598 [&](InlVec<T>* vec, size_t) {
606 template <
typename T,
size_t FromSize,
size_t ToSize>
608 using VecT = InlVec<T>;
609 std::array<VecT, kBatchSize> vector_batch{};
613 [&](InlVec<T>* vec,
size_t i) {
614 vector_batch[
i].clear();
615 vector_batch[
i].resize(ToSize);
616 vec->resize(FromSize);
619 [&](InlVec<T>* vec,
size_t i) {
627 template <
typename T,
size_t FromSize,
size_t ToSize>
632 [](InlVec<T>* vec,
size_t) {
634 vec->resize(FromSize);
637 [](InlVec<T>* vec, size_t) { vec->resize(ToSize); });
642 template <
typename T,
size_t FromSize,
size_t ToSize>
648 [](InlVec<T>* vec,
size_t) {
650 vec->resize(FromSize);
653 [&](InlVec<T>* vec, size_t) {
655 vec->resize(ToSize, t);
661 template <
typename T,
size_t FromSize,
size_t ToSize>
667 [](InlVec<T>* vec,
size_t) {
669 vec->resize(FromSize);
672 [&](InlVec<T>* vec, size_t) {
674 auto*
pos = vec->data() + (vec->size() / 2);
681 template <
typename T,
size_t FromSize,
size_t ToSize>
683 InlVec<T> other_vec(ToSize);
687 [](InlVec<T>* vec,
size_t) {
689 vec->resize(FromSize);
692 [&](InlVec<T>* vec, size_t) {
694 auto*
pos = vec->data() + (vec->size() / 2);
695 vec->insert(
pos, other_vec.begin(), other_vec.end());
701 template <
typename T,
size_t FromSize>
706 [](InlVec<T>* vec,
size_t) {
708 vec->resize(FromSize);
711 [](InlVec<T>* vec, size_t) { vec->emplace_back(); });
716 template <
typename T,
size_t FromSize>
721 [](InlVec<T>* vec,
size_t) {
723 vec->resize(FromSize);
726 [](InlVec<T>* vec, size_t) { vec->pop_back(); });
731 template <
typename T,
size_t FromSize>
736 [](InlVec<T>* vec,
size_t) {
738 vec->resize(FromSize);
741 [](InlVec<T>* vec, size_t) {
742 auto*
pos = vec->data() + (vec->size() / 2);
749 template <
typename T,
size_t FromSize>
754 [](InlVec<T>* vec,
size_t) {
756 vec->resize(FromSize);
759 [](InlVec<T>* vec, size_t) {
760 auto*
pos = vec->data() + (vec->size() / 2);
767 template <
typename T,
size_t FromSize>
771 [](InlVec<T>* vec,
size_t) { vec->resize(FromSize); },
772 [](InlVec<T>* vec, size_t) { vec->clear(); });
777 template <
typename T,
size_t FromSize,
size_t ToCapacity>
782 [](InlVec<T>* vec,
size_t) {
784 vec->resize(FromSize);
787 [](InlVec<T>* vec, size_t) { vec->reserve(ToCapacity); });
792 template <
typename T,
size_t FromCapacity,
size_t ToCapacity>
797 [](InlVec<T>* vec,
size_t) {
799 vec->resize(ToCapacity);
800 vec->reserve(FromCapacity);
802 [](InlVec<T>* vec, size_t) { vec->shrink_to_fit(); });
807 template <
typename T,
size_t FromSize,
size_t ToSize>
809 using VecT = InlVec<T>;
810 std::array<VecT, kBatchSize> vector_batch{};
814 [&](InlVec<T>* vec,
size_t i) {
815 vector_batch[
i].clear();
816 vector_batch[
i].resize(ToSize);
817 vec->resize(FromSize);
820 [&](InlVec<T>* vec,
size_t i) {
823 swap(*vec, vector_batch[
i]);