// Copyright 2020 The Division 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 // // https://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. // Author dietoad@gmail.com && firedtoad@gmail.com #include "container/SortedVector.h" #include "tsl/ordered_set.h" #include #include #include static unsigned long xorshf96() { /* A George Marsaglia generator, period 2^96-1 */ static unsigned long x = 103456789, y = 362436069, z = 521088629; unsigned long t; x ^= x << 16; x ^= x >> 5; x ^= x << 1; t = x; x = y; y = z; z = t ^ x ^ y; return z; } static inline unsigned long _random() { return xorshf96(); } template static void BenchInsert(benchmark::State &state) { for (auto _ : state) { V v; for (auto i = 0; i < state.range(0); i++) { auto r = _random(); v.insert(r); } } } BENCHMARK_TEMPLATE(BenchInsert, sorted_vector)->Range(1, 1 << 10); BENCHMARK_TEMPLATE(BenchInsert, std::set)->Range(1, 1 << 10); BENCHMARK_TEMPLATE(BenchInsert, tsl::ordered_set)->Range(1, 1 << 10); struct Pod { uint64_t i; uint64_t j; bool operator<(const Pod &p) const { return i < p.i; } }; struct PodMap { uint64_t i; PodMap() noexcept = default; PodMap(uint64_t i_) : i(i_) {} }; struct PodHash { size_t operator()(const Pod &p) const { return p.i; } }; struct PodEqual { size_t operator()(const Pod &p1, const Pod &p2) const { return p1.i == p2.i; } }; template static void BenchInsertPod(benchmark::State &state) { for (auto _ : state) { V v; for (auto i = 0; i < state.range(0); i++) { Pod pod{static_cast(_random()), 0}; v.insert(pod); } } } template static void BenchInsertPodMap(benchmark::State &state) { for (auto _ : state) { V v; for (auto i = 0; i < state.range(0); i++) { auto r = _random(); v.insert(r, {r}); } } } BENCHMARK_TEMPLATE(BenchInsertPod, sorted_vector)->Range(1, 1 << 10); BENCHMARK_TEMPLATE(BenchInsertPodMap, sorted_vector_map)->Range(8, 1 << 10); BENCHMARK_TEMPLATE(BenchInsertPod, std::set)->Range(1, 1 << 10); BENCHMARK_TEMPLATE(BenchInsertPod, tsl::ordered_set)->Range(1, 1 << 10); template static void BenchFind(benchmark::State &state) { V v; for (auto i = 0; i < state.range(0); i++) { v.insert(_random() % 65536); } for (auto _ : state) { auto it = v.find(_random() % 65536); benchmark::DoNotOptimize(it); } } BENCHMARK_TEMPLATE(BenchFind, sorted_vector)->Range(1, 1 << 10); BENCHMARK_TEMPLATE(BenchFind, std::set)->Range(1, 1 << 10); BENCHMARK_TEMPLATE(BenchFind, tsl::ordered_set)->Range(1, 1 << 10); template static void BenchRange(benchmark::State &state) { V v; for (auto i = 0; i < state.range(0); i++) { v.insert(_random()); } auto sum = 0; for (auto _ : state) { for (auto &it : v) { sum += it; } } benchmark::DoNotOptimize(sum); } BENCHMARK_TEMPLATE(BenchRange, sorted_vector)->Range(1, 1 << 10); BENCHMARK_TEMPLATE(BenchRange, std::set)->Range(1, 1 << 10); BENCHMARK_TEMPLATE(BenchRange, tsl::ordered_set)->Range(1, 1 << 10); template static void BenchErase(benchmark::State &state) { V v; for (auto i = 0; i < state.range(0); i++) { v.insert(_random() % 65536); } for (auto _ : state) { auto r = _random() % 65536; auto it = v.erase(r); if (it > 0) { v.insert(r); } } } BENCHMARK_TEMPLATE(BenchErase, sorted_vector)->Range(1, 1 << 10); BENCHMARK_TEMPLATE(BenchErase, std::set)->Range(1, 1 << 10); BENCHMARK_TEMPLATE(BenchErase, tsl::ordered_set)->Range(1, 1 << 10); int main(int argc, char **argv) { benchmark::Initialize(&argc, argv); benchmark::RunSpecifiedBenchmarks(); return 0; }