aboutsummaryrefslogtreecommitdiffhomepage
path: root/absl/container/inlined_vector_benchmark.cc
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2018-05-04 09:58:56 -0700
committerGravatar vslashg <gfalcon@google.com>2018-05-04 13:30:42 -0400
commit26b789f9a53d086c8b8c9c2668efb251e37861cd (patch)
tree9fdcdfa6f42993dd9abce0498d18810911765211 /absl/container/inlined_vector_benchmark.cc
parent9613678332c976568272c8f4a78631a29159271d (diff)
- 07191b0f52301e1e4a790e236f7b7c2fd90561ae Disambiguates computed return type of absl::optional logi... by Abseil Team <absl-team@google.com>
- acd95f8ec4e6ec1587cb198c7f40af3c81094d92 Release container benchmarks. by Alex Strelnikov <strel@google.com> - 80f596b6b7c5e06453e778c16527d5a0e85f8413 Allow absl::base_internal::AtomicHook to have a default v... by Derek Mauro <dmauro@google.com> - 8402631546af8bcbd4acdf897d0cdfb805ad544a Release thread_identity benchmark. by Alex Strelnikov <strel@google.com> - 6dcb1e90fefb8556ce4654983d3a73c7585b4b99 Fix spelling error in variant.h by Abseil Team <absl-team@google.com> - faa8a81e1442018c0d400b09a595a5be55074715 Run tests from CMake. The CI is currently Linux only, fo... by Jon Cohen <cohenjon@google.com> - 745ed6db574f931f2ec3a88e964fb03a5f22f816 Internal change. by Derek Mauro <dmauro@google.com> - 23facd7d1c5f43ac8181b016ee4acc5955f048c1 absl::variant exception safety test. by Xiaoyi Zhang <zhangxy@google.com> - c18e21e7cf8f6e83ae9d90e536e886409dd6cf68 Reinstate the syntax check on time-zone abbreviations now... by Abseil Team <absl-team@google.com> - da469f4314f0c820665a2b5b9477af9462b23e42 Import CCTZ changes to internal copy. by Shaindel Schwartz <shaindel@google.com> - 44ea35843517be03ab256b69449ccfea64352621 Import CCTZ changes to internal copy. by Abseil Team <absl-team@google.com> - 55d1105312687c6093950fac831c7540f49045b5 Import CCTZ changes to internal copy. by Greg Falcon <gfalcon@google.com> - 58d7965ad274406410b6d833213eca04d41c6867 Add zoneinfo as a data dependency to the //absl/time tests. by Shaindel Schwartz <shaindel@google.com> - 6acc50146f9ff29015bfaaa5bf9900691f839da5 Change benchmark target type from cc_test to cc_binary. by Alex Strelnikov <strel@google.com> - db3fbdae8f9f285a466f7a070326b1ce43b6a0dd Update WORKSPACE for C++ microbenchmarks and release algo... by Alex Strelnikov <strel@google.com> - 0869ae168255242af651853ed01719166d8cebf6 Update to Bazel version 0.13.0. by Abseil Team <absl-team@google.com> - e507dd53ab788964207fdf27d31b72a33c296fab Add missing include of cstdio by Abseil Team <absl-team@google.com> GitOrigin-RevId: 07191b0f52301e1e4a790e236f7b7c2fd90561ae Change-Id: I90994cf2b438fbec894724dcd9b90882281eef56
Diffstat (limited to 'absl/container/inlined_vector_benchmark.cc')
-rw-r--r--absl/container/inlined_vector_benchmark.cc376
1 files changed, 376 insertions, 0 deletions
diff --git a/absl/container/inlined_vector_benchmark.cc b/absl/container/inlined_vector_benchmark.cc
new file mode 100644
index 0000000..a2035e3
--- /dev/null
+++ b/absl/container/inlined_vector_benchmark.cc
@@ -0,0 +1,376 @@
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/container/inlined_vector.h"
+
+#include <string>
+#include <vector>
+
+#include "absl/base/internal/raw_logging.h"
+#include "absl/strings/str_cat.h"
+#include "benchmark/benchmark.h"
+
+namespace {
+
+using IntVec = absl::InlinedVector<int, 8>;
+
+void BM_InlinedVectorFill(benchmark::State& state) {
+ const int len = state.range(0);
+ for (auto _ : state) {
+ IntVec v;
+ for (int i = 0; i < len; i++) {
+ v.push_back(i);
+ }
+ }
+ state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len);
+}
+BENCHMARK(BM_InlinedVectorFill)->Range(0, 1024);
+
+void BM_InlinedVectorFillRange(benchmark::State& state) {
+ const int len = state.range(0);
+ std::unique_ptr<int[]> ia(new int[len]);
+ for (int i = 0; i < len; i++) {
+ ia[i] = i;
+ }
+ for (auto _ : state) {
+ IntVec v(ia.get(), ia.get() + len);
+ benchmark::DoNotOptimize(v);
+ }
+ state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len);
+}
+BENCHMARK(BM_InlinedVectorFillRange)->Range(0, 1024);
+
+void BM_StdVectorFill(benchmark::State& state) {
+ const int len = state.range(0);
+ for (auto _ : state) {
+ std::vector<int> v;
+ for (int i = 0; i < len; i++) {
+ v.push_back(i);
+ }
+ }
+ state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len);
+}
+BENCHMARK(BM_StdVectorFill)->Range(0, 1024);
+
+bool StringRepresentedInline(std::string s) {
+ const char* chars = s.data();
+ std::string s1 = std::move(s);
+ return s1.data() != chars;
+}
+
+void BM_InlinedVectorFillString(benchmark::State& state) {
+ const int len = state.range(0);
+ std::string strings[4] = {"a quite long string",
+ "another long string",
+ "012345678901234567",
+ "to cause allocation"};
+ for (auto _ : state) {
+ absl::InlinedVector<std::string, 8> v;
+ for (int i = 0; i < len; i++) {
+ v.push_back(strings[i & 3]);
+ }
+ }
+ state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len);
+}
+BENCHMARK(BM_InlinedVectorFillString)->Range(0, 1024);
+
+void BM_StdVectorFillString(benchmark::State& state) {
+ const int len = state.range(0);
+ std::string strings[4] = {"a quite long string",
+ "another long string",
+ "012345678901234567",
+ "to cause allocation"};
+ for (auto _ : state) {
+ std::vector<std::string> v;
+ for (int i = 0; i < len; i++) {
+ v.push_back(strings[i & 3]);
+ }
+ }
+ state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len);
+ // The purpose of the benchmark is to verify that inlined vector is
+ // efficient when moving is more efficent than copying. To do so, we
+ // use strings that are larger than the small std::string optimization.
+ ABSL_RAW_CHECK(!StringRepresentedInline(strings[0]),
+ "benchmarked with strings that are too small");
+}
+BENCHMARK(BM_StdVectorFillString)->Range(0, 1024);
+
+struct Buffer { // some arbitrary structure for benchmarking.
+ char* base;
+ int length;
+ int capacity;
+ void* user_data;
+};
+
+void BM_InlinedVectorTenAssignments(benchmark::State& state) {
+ const int len = state.range(0);
+ using BufferVec = absl::InlinedVector<Buffer, 2>;
+
+ BufferVec src;
+ src.resize(len);
+
+ BufferVec dst;
+ for (auto _ : state) {
+ for (int i = 0; i < 10; ++i) {
+ dst = src;
+ }
+ }
+}
+BENCHMARK(BM_InlinedVectorTenAssignments)
+ ->Arg(0)->Arg(1)->Arg(2)->Arg(3)->Arg(4)->Arg(20);
+
+void BM_CreateFromContainer(benchmark::State& state) {
+ for (auto _ : state) {
+ absl::InlinedVector<int, 4> x(absl::InlinedVector<int, 4>{1, 2, 3});
+ benchmark::DoNotOptimize(x);
+ }
+}
+BENCHMARK(BM_CreateFromContainer);
+
+struct LargeCopyableOnly {
+ LargeCopyableOnly() : d(1024, 17) {}
+ LargeCopyableOnly(const LargeCopyableOnly& o) = default;
+ LargeCopyableOnly& operator=(const LargeCopyableOnly& o) = default;
+
+ std::vector<int> d;
+};
+
+struct LargeCopyableSwappable {
+ LargeCopyableSwappable() : d(1024, 17) {}
+ LargeCopyableSwappable(const LargeCopyableSwappable& o) = default;
+ LargeCopyableSwappable(LargeCopyableSwappable&& o) = delete;
+
+ LargeCopyableSwappable& operator=(LargeCopyableSwappable o) {
+ using std::swap;
+ swap(*this, o);
+ return *this;
+ }
+ LargeCopyableSwappable& operator=(LargeCopyableSwappable&& o) = delete;
+
+ friend void swap(LargeCopyableSwappable& a, LargeCopyableSwappable& b) {
+ using std::swap;
+ swap(a.d, b.d);
+ }
+
+ std::vector<int> d;
+};
+
+struct LargeCopyableMovable {
+ LargeCopyableMovable() : d(1024, 17) {}
+ // Use implicitly defined copy and move.
+
+ std::vector<int> d;
+};
+
+struct LargeCopyableMovableSwappable {
+ LargeCopyableMovableSwappable() : d(1024, 17) {}
+ LargeCopyableMovableSwappable(const LargeCopyableMovableSwappable& o) =
+ default;
+ LargeCopyableMovableSwappable(LargeCopyableMovableSwappable&& o) = default;
+
+ LargeCopyableMovableSwappable& operator=(LargeCopyableMovableSwappable o) {
+ using std::swap;
+ swap(*this, o);
+ return *this;
+ }
+ LargeCopyableMovableSwappable& operator=(LargeCopyableMovableSwappable&& o) =
+ default;
+
+ friend void swap(LargeCopyableMovableSwappable& a,
+ LargeCopyableMovableSwappable& b) {
+ using std::swap;
+ swap(a.d, b.d);
+ }
+
+ std::vector<int> d;
+};
+
+template <typename ElementType>
+void BM_SwapElements(benchmark::State& state) {
+ const int len = state.range(0);
+ using Vec = absl::InlinedVector<ElementType, 32>;
+ Vec a(len);
+ Vec b;
+ for (auto _ : state) {
+ using std::swap;
+ swap(a, b);
+ }
+}
+BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableOnly)->Range(0, 1024);
+BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableSwappable)->Range(0, 1024);
+BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableMovable)->Range(0, 1024);
+BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableMovableSwappable)
+ ->Range(0, 1024);
+
+// The following benchmark is meant to track the efficiency of the vector size
+// as a function of stored type via the benchmark label. It is not meant to
+// output useful sizeof operator performance. The loop is a dummy operation
+// to fulfill the requirement of running the benchmark.
+template <typename VecType>
+void BM_Sizeof(benchmark::State& state) {
+ int size = 0;
+ for (auto _ : state) {
+ VecType vec;
+ size = sizeof(vec);
+ }
+ state.SetLabel(absl::StrCat("sz=", size));
+}
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<char, 1>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<char, 4>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<char, 7>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<char, 8>);
+
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<int, 1>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<int, 4>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<int, 7>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<int, 8>);
+
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<void*, 1>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<void*, 4>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<void*, 7>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<void*, 8>);
+
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<std::string, 1>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<std::string, 4>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<std::string, 7>);
+BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector<std::string, 8>);
+
+void BM_InlinedVectorIndexInlined(benchmark::State& state) {
+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7};
+ for (auto _ : state) {
+ for (int i = 0; i < 1000; ++i) {
+ benchmark::DoNotOptimize(v);
+ benchmark::DoNotOptimize(v[4]);
+ }
+ }
+ state.SetItemsProcessed(1000 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_InlinedVectorIndexInlined);
+
+void BM_InlinedVectorIndexExternal(benchmark::State& state) {
+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ for (auto _ : state) {
+ for (int i = 0; i < 1000; ++i) {
+ benchmark::DoNotOptimize(v);
+ benchmark::DoNotOptimize(v[4]);
+ }
+ }
+ state.SetItemsProcessed(1000 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_InlinedVectorIndexExternal);
+
+void BM_StdVectorIndex(benchmark::State& state) {
+ std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ for (auto _ : state) {
+ for (int i = 0; i < 1000; ++i) {
+ benchmark::DoNotOptimize(v);
+ benchmark::DoNotOptimize(v[4]);
+ }
+ }
+ state.SetItemsProcessed(1000 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_StdVectorIndex);
+
+#define UNROLL_2(x) \
+ benchmark::DoNotOptimize(x); \
+ benchmark::DoNotOptimize(x);
+
+#define UNROLL_4(x) UNROLL_2(x) UNROLL_2(x)
+#define UNROLL_8(x) UNROLL_4(x) UNROLL_4(x)
+#define UNROLL_16(x) UNROLL_8(x) UNROLL_8(x);
+
+void BM_InlinedVectorDataInlined(benchmark::State& state) {
+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7};
+ for (auto _ : state) {
+ UNROLL_16(v.data());
+ }
+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_InlinedVectorDataInlined);
+
+void BM_InlinedVectorDataExternal(benchmark::State& state) {
+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ for (auto _ : state) {
+ UNROLL_16(v.data());
+ }
+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_InlinedVectorDataExternal);
+
+void BM_StdVectorData(benchmark::State& state) {
+ std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ for (auto _ : state) {
+ UNROLL_16(v.data());
+ }
+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_StdVectorData);
+
+void BM_InlinedVectorSizeInlined(benchmark::State& state) {
+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7};
+ for (auto _ : state) {
+ UNROLL_16(v.size());
+ }
+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_InlinedVectorSizeInlined);
+
+void BM_InlinedVectorSizeExternal(benchmark::State& state) {
+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ for (auto _ : state) {
+ UNROLL_16(v.size());
+ }
+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_InlinedVectorSizeExternal);
+
+void BM_StdVectorSize(benchmark::State& state) {
+ std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ for (auto _ : state) {
+ UNROLL_16(v.size());
+ }
+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_StdVectorSize);
+
+void BM_InlinedVectorEmptyInlined(benchmark::State& state) {
+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7};
+ for (auto _ : state) {
+ UNROLL_16(v.empty());
+ }
+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_InlinedVectorEmptyInlined);
+
+void BM_InlinedVectorEmptyExternal(benchmark::State& state) {
+ absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ for (auto _ : state) {
+ UNROLL_16(v.empty());
+ }
+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_InlinedVectorEmptyExternal);
+
+void BM_StdVectorEmpty(benchmark::State& state) {
+ std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ for (auto _ : state) {
+ UNROLL_16(v.empty());
+ }
+ state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
+}
+BENCHMARK(BM_StdVectorEmpty);
+
+} // namespace
+
+BENCHMARK_MAIN();