-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add runtime benchmarks for
Fixed*Map
data structures
This adds a new set of tests tagged "benchmark" in bazel, which are filtered out of the default `test_suite` target. This means that they will only be built/run manually.
- Loading branch information
1 parent
3a45dbd
commit dcff589
Showing
8 changed files
with
557 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#include "fixed_containers/fixed_map.hpp" | ||
#include "fixed_containers/fixed_unordered_map.hpp" | ||
|
||
#include <benchmark/benchmark.h> | ||
|
||
#include <array> | ||
#include <cstddef> | ||
#include <cstdint> | ||
#include <map> | ||
#include <unordered_map> | ||
|
||
namespace fixed_containers | ||
{ | ||
|
||
namespace | ||
{ | ||
template <typename MapType> | ||
void benchmark_map_copy(benchmark::State& state) | ||
{ | ||
const int64_t nelem = state.range(0); | ||
MapType instance = {}; | ||
|
||
using KeyType = typename MapType::key_type; | ||
for (int64_t i = 0; i < nelem; i++) | ||
{ | ||
instance.try_emplace(static_cast<KeyType>(i)); | ||
} | ||
|
||
for (auto _ : state) | ||
{ | ||
MapType instance2{instance}; | ||
benchmark::DoNotOptimize(instance2); | ||
} | ||
} | ||
|
||
template <typename MapType> | ||
void benchmark_map_copy_then_clear(benchmark::State& state) | ||
{ | ||
using KeyType = typename MapType::key_type; | ||
MapType instance{}; | ||
const int64_t nelem = state.range(0); | ||
for (int64_t i = 0; i < nelem; i++) | ||
{ | ||
instance.try_emplace(static_cast<KeyType>(i)); | ||
} | ||
|
||
for (auto _ : state) | ||
{ | ||
MapType instance2{instance}; | ||
instance2.clear(); | ||
benchmark::DoNotOptimize(instance2); | ||
} | ||
} | ||
|
||
template <typename MapType> | ||
void benchmark_map_copy_then_reconstruct(benchmark::State& state) | ||
{ | ||
using KeyType = typename MapType::key_type; | ||
MapType instance{}; | ||
const int64_t nelem = state.range(0); | ||
for (int64_t i = 0; i < nelem; i++) | ||
{ | ||
instance.try_emplace(static_cast<KeyType>(i)); | ||
} | ||
|
||
for (auto _ : state) | ||
{ | ||
MapType instance2{instance}; | ||
instance2 = {}; | ||
benchmark::DoNotOptimize(instance2); | ||
} | ||
} | ||
|
||
template <typename ArrType> | ||
void benchmark_array_clear(benchmark::State& state) | ||
{ | ||
ArrType instance{}; | ||
|
||
for (auto _ : state) | ||
{ | ||
instance.fill(0); | ||
benchmark::DoNotOptimize(instance); | ||
} | ||
} | ||
} // namespace | ||
|
||
constexpr std::size_t MAX_SIZE = 8 << 13; | ||
|
||
BENCHMARK(benchmark_map_copy<std::map<int, int>>)->Range(16, MAX_SIZE); | ||
BENCHMARK(benchmark_map_copy_then_clear<std::map<int, int>>)->Range(16, MAX_SIZE); | ||
BENCHMARK(benchmark_map_copy_then_reconstruct<std::map<int, int>>)->Range(16, MAX_SIZE); | ||
|
||
BENCHMARK(benchmark_map_copy<std::unordered_map<int, int>>)->Range(16, MAX_SIZE); | ||
BENCHMARK(benchmark_map_copy_then_clear<std::unordered_map<int, int>>)->Range(16, MAX_SIZE); | ||
BENCHMARK(benchmark_map_copy_then_reconstruct<std::unordered_map<int, int>>)->Range(16, MAX_SIZE); | ||
|
||
BENCHMARK(benchmark_map_copy<FixedMap<int, int, MAX_SIZE>>)->Range(16, MAX_SIZE); | ||
BENCHMARK(benchmark_map_copy_then_clear<FixedMap<int, int, MAX_SIZE>>)->Range(16, MAX_SIZE); | ||
BENCHMARK(benchmark_map_copy_then_reconstruct<FixedMap<int, int, MAX_SIZE>>)->Range(16, MAX_SIZE); | ||
|
||
BENCHMARK(benchmark_map_copy<FixedUnorderedMap<int, int, MAX_SIZE>>)->Range(16, MAX_SIZE); | ||
BENCHMARK(benchmark_map_copy_then_clear<FixedUnorderedMap<int, int, MAX_SIZE>>) | ||
->Range(16, MAX_SIZE); | ||
BENCHMARK(benchmark_map_copy_then_reconstruct<FixedUnorderedMap<int, int, MAX_SIZE>>) | ||
->Range(16, MAX_SIZE); | ||
|
||
// more-or-less the theoretical best performance we could possibly get for a full FixedUnorderedMap | ||
// (just 0 out every bucket) | ||
BENCHMARK(benchmark_array_clear<std::array<long, (MAX_SIZE * 130ULL) / 100>>); | ||
|
||
} // namespace fixed_containers | ||
|
||
BENCHMARK_MAIN(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#include "map_utils.hpp" | ||
|
||
#include "../mock_testing_types.hpp" | ||
#include "fixed_containers/fixed_unordered_map.hpp" | ||
|
||
#include <benchmark/benchmark.h> | ||
|
||
#include <cstdint> | ||
|
||
namespace fixed_containers | ||
{ | ||
|
||
namespace | ||
{ | ||
template <typename MapType> | ||
void benchmark_map_copy_fresh(benchmark::State& state) | ||
{ | ||
const int64_t nelem = state.range(0); | ||
MapType instance = {}; | ||
|
||
using KeyType = typename MapType::key_type; | ||
for (int64_t i = 0; i < nelem; i++) | ||
{ | ||
instance.try_emplace(static_cast<KeyType>(i)); | ||
} | ||
|
||
for (auto _ : state) | ||
{ | ||
MapType instance2{instance}; | ||
benchmark::DoNotOptimize(instance2); | ||
} | ||
} | ||
|
||
template <typename MapType> | ||
void benchmark_map_iterate_copy_fresh(benchmark::State& state) | ||
{ | ||
const int64_t nelem = state.range(0); | ||
MapType instance = {}; | ||
|
||
using KeyType = typename MapType::key_type; | ||
for (int64_t i = 0; i < nelem; i++) | ||
{ | ||
instance.try_emplace(static_cast<KeyType>(i)); | ||
} | ||
|
||
for (auto _ : state) | ||
{ | ||
MapType instance2{}; | ||
for (auto elem : instance) | ||
{ | ||
instance2.try_emplace(elem.first, elem.second); | ||
} | ||
benchmark::DoNotOptimize(instance2); | ||
} | ||
} | ||
|
||
template <typename MapType> | ||
void benchmark_map_copy_shuffled(benchmark::State& state) | ||
{ | ||
const int64_t nelem = state.range(0); | ||
auto instance = map_benchmarks::make_shuffled_map<MapType>(); | ||
|
||
using KeyType = typename MapType::key_type; | ||
for (int64_t i = 0; i < nelem; i++) | ||
{ | ||
instance.try_emplace(static_cast<KeyType>(i)); | ||
} | ||
|
||
for (auto _ : state) | ||
{ | ||
MapType instance2{instance}; | ||
benchmark::DoNotOptimize(instance2); | ||
} | ||
} | ||
|
||
template <typename MapType> | ||
void benchmark_map_iterate_copy_shuffled(benchmark::State& state) | ||
{ | ||
const int64_t nelem = state.range(0); | ||
auto instance = map_benchmarks::make_shuffled_map<MapType>(); | ||
|
||
using KeyType = typename MapType::key_type; | ||
for (int64_t i = 0; i < nelem; i++) | ||
{ | ||
instance.try_emplace(static_cast<KeyType>(i)); | ||
} | ||
|
||
for (auto _ : state) | ||
{ | ||
MapType instance2{}; | ||
for (auto elem : instance) | ||
{ | ||
instance2.try_emplace(elem.first, elem.second); | ||
} | ||
benchmark::DoNotOptimize(instance2); | ||
} | ||
} | ||
} // namespace | ||
|
||
BENCHMARK( | ||
benchmark_map_copy_fresh<FixedUnorderedMap<int, MockNonTrivialCopyConstructible, 8 << 14>>) | ||
->DenseRange(1024, 8 << 14, 1024); | ||
BENCHMARK(benchmark_map_iterate_copy_fresh< | ||
FixedUnorderedMap<int, MockNonTrivialCopyConstructible, 8 << 14>>) | ||
->DenseRange(1024, 8 << 14, 1024); | ||
|
||
BENCHMARK( | ||
benchmark_map_copy_shuffled<FixedUnorderedMap<int, MockNonTrivialCopyConstructible, 8 << 14>>) | ||
->DenseRange(1024, 8 << 14, 1024); | ||
BENCHMARK(benchmark_map_iterate_copy_shuffled< | ||
FixedUnorderedMap<int, MockNonTrivialCopyConstructible, 8 << 14>>) | ||
->DenseRange(1024, 8 << 14, 1024); | ||
|
||
} // namespace fixed_containers | ||
|
||
BENCHMARK_MAIN(); |
Oops, something went wrong.