diff options
author | 2021-01-02 20:29:13 +0000 | |
---|---|---|
committer | 2021-01-02 20:29:13 +0000 | |
commit | 46035553bfdd96e63c94e32da0210227ec2e3cf1 (patch) | |
tree | b191f708fb9a2995ba745b2f31cdeeaee4872b7f /gnu/llvm/libcxx/benchmarks/ordered_set.bench.cpp | |
parent | Move Makefiles for libc++ and libc++abi to gnu/lib in preparation for an (diff) | |
download | wireguard-openbsd-46035553bfdd96e63c94e32da0210227ec2e3cf1.tar.xz wireguard-openbsd-46035553bfdd96e63c94e32da0210227ec2e3cf1.zip |
Import libc++ 10.0.1 release.
Diffstat (limited to 'gnu/llvm/libcxx/benchmarks/ordered_set.bench.cpp')
-rw-r--r-- | gnu/llvm/libcxx/benchmarks/ordered_set.bench.cpp | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/gnu/llvm/libcxx/benchmarks/ordered_set.bench.cpp b/gnu/llvm/libcxx/benchmarks/ordered_set.bench.cpp new file mode 100644 index 00000000000..a9d9c929ac6 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/ordered_set.bench.cpp @@ -0,0 +1,248 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <algorithm> +#include <cstdint> +#include <memory> +#include <random> +#include <set> +#include <string> +#include <vector> + +#include "CartesianBenchmarks.h" +#include "benchmark/benchmark.h" +#include "test_macros.h" + +namespace { + +enum class HitType { Hit, Miss }; + +struct AllHitTypes : EnumValuesAsTuple<AllHitTypes, HitType, 2> { + static constexpr const char* Names[] = {"Hit", "Miss"}; +}; + +enum class AccessPattern { Ordered, Random }; + +struct AllAccessPattern + : EnumValuesAsTuple<AllAccessPattern, AccessPattern, 2> { + static constexpr const char* Names[] = {"Ordered", "Random"}; +}; + +void sortKeysBy(std::vector<uint64_t>& Keys, AccessPattern AP) { + if (AP == AccessPattern::Random) { + std::random_device R; + std::mt19937 M(R()); + std::shuffle(std::begin(Keys), std::end(Keys), M); + } +} + +struct TestSets { + std::vector<std::set<uint64_t> > Sets; + std::vector<uint64_t> Keys; +}; + +TestSets makeTestingSets(size_t TableSize, size_t NumTables, HitType Hit, + AccessPattern Access) { + TestSets R; + R.Sets.resize(1); + + for (uint64_t I = 0; I < TableSize; ++I) { + R.Sets[0].insert(2 * I); + R.Keys.push_back(Hit == HitType::Hit ? 2 * I : 2 * I + 1); + } + R.Sets.resize(NumTables, R.Sets[0]); + sortKeysBy(R.Keys, Access); + + return R; +} + +struct Base { + size_t TableSize; + size_t NumTables; + Base(size_t T, size_t N) : TableSize(T), NumTables(N) {} + + bool skip() const { + size_t Total = TableSize * NumTables; + return Total < 100 || Total > 1000000; + } + + std::string baseName() const { + return "_TableSize" + std::to_string(TableSize) + "_NumTables" + + std::to_string(NumTables); + } +}; + +template <class Access> +struct Create : Base { + using Base::Base; + + void run(benchmark::State& State) const { + std::vector<uint64_t> Keys(TableSize); + std::iota(Keys.begin(), Keys.end(), uint64_t{0}); + sortKeysBy(Keys, Access()); + + while (State.KeepRunningBatch(TableSize * NumTables)) { + std::vector<std::set<uint64_t>> Sets(NumTables); + for (auto K : Keys) { + for (auto& Set : Sets) { + benchmark::DoNotOptimize(Set.insert(K)); + } + } + } + } + + std::string name() const { + return "BM_Create" + Access::name() + baseName(); + } +}; + +template <class Hit, class Access> +struct Find : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access()); + + while (State.KeepRunningBatch(TableSize * NumTables)) { + for (auto K : Data.Keys) { + for (auto& Set : Data.Sets) { + benchmark::DoNotOptimize(Set.find(K)); + } + } + } + } + + std::string name() const { + return "BM_Find" + Hit::name() + Access::name() + baseName(); + } +}; + +template <class Hit, class Access> +struct FindNeEnd : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access()); + + while (State.KeepRunningBatch(TableSize * NumTables)) { + for (auto K : Data.Keys) { + for (auto& Set : Data.Sets) { + benchmark::DoNotOptimize(Set.find(K) != Set.end()); + } + } + } + } + + std::string name() const { + return "BM_FindNeEnd" + Hit::name() + Access::name() + baseName(); + } +}; + +template <class Access> +struct InsertHit : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(TableSize, NumTables, HitType::Hit, Access()); + + while (State.KeepRunningBatch(TableSize * NumTables)) { + for (auto K : Data.Keys) { + for (auto& Set : Data.Sets) { + benchmark::DoNotOptimize(Set.insert(K)); + } + } + } + } + + std::string name() const { + return "BM_InsertHit" + Access::name() + baseName(); + } +}; + +template <class Access> +struct InsertMissAndErase : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss, Access()); + + while (State.KeepRunningBatch(TableSize * NumTables)) { + for (auto K : Data.Keys) { + for (auto& Set : Data.Sets) { + benchmark::DoNotOptimize(Set.erase(Set.insert(K).first)); + } + } + } + } + + std::string name() const { + return "BM_InsertMissAndErase" + Access::name() + baseName(); + } +}; + +struct IterateRangeFor : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss, + AccessPattern::Ordered); + + while (State.KeepRunningBatch(TableSize * NumTables)) { + for (auto& Set : Data.Sets) { + for (auto& V : Set) { + benchmark::DoNotOptimize(V); + } + } + } + } + + std::string name() const { return "BM_IterateRangeFor" + baseName(); } +}; + +struct IterateBeginEnd : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss, + AccessPattern::Ordered); + + while (State.KeepRunningBatch(TableSize * NumTables)) { + for (auto& Set : Data.Sets) { + for (auto it = Set.begin(); it != Set.end(); ++it) { + benchmark::DoNotOptimize(*it); + } + } + } + } + + std::string name() const { return "BM_IterateBeginEnd" + baseName(); } +}; + +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + const std::vector<size_t> TableSize{1, 10, 100, 1000, 10000, 100000, 1000000}; + const std::vector<size_t> NumTables{1, 10, 100, 1000, 10000, 100000, 1000000}; + + makeCartesianProductBenchmark<Create, AllAccessPattern>(TableSize, NumTables); + makeCartesianProductBenchmark<Find, AllHitTypes, AllAccessPattern>( + TableSize, NumTables); + makeCartesianProductBenchmark<FindNeEnd, AllHitTypes, AllAccessPattern>( + TableSize, NumTables); + makeCartesianProductBenchmark<InsertHit, AllAccessPattern>( + TableSize, NumTables); + makeCartesianProductBenchmark<InsertMissAndErase, AllAccessPattern>( + TableSize, NumTables); + makeCartesianProductBenchmark<IterateRangeFor>(TableSize, NumTables); + makeCartesianProductBenchmark<IterateBeginEnd>(TableSize, NumTables); + benchmark::RunSpecifiedBenchmarks(); +} |