Skip to content

Commit 9a9e357

Browse files
committed
Add benchmark about comparaison of operator[] and at()
1 parent d3eccc3 commit 9a9e357

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

Curiosity/access--benchmark.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//#region [Headers]
2+
#include <array>
3+
#include <benchmark/benchmark.h>
4+
#include <map>
5+
#include <type_traits>
6+
#include <unordered_map>
7+
#include <vector>
8+
//#endregion
9+
//#region [Configs]
10+
#define COUNT 500
11+
#define SIZE 1000
12+
13+
// local traits
14+
struct UnsafeMode {};
15+
struct SafeMode {};
16+
struct InOrder {};
17+
struct RandomOrder {};
18+
//#endregion
19+
//#region [Dummy structures]
20+
struct DummyValue {
21+
template <typename T> void operator=(const T &) {}
22+
operator int() { return 1; }
23+
};
24+
struct DummyContainer {
25+
DummyValue operator[](std::size_t) { return {}; }
26+
DummyValue at(std::size_t) { return {}; }
27+
};
28+
//#endregion
29+
30+
template <typename Mode, typename Order, typename Container, auto... args>
31+
void bench(benchmark::State &state) {
32+
benchmark::ClobberMemory();
33+
Container c(args...);
34+
benchmark::DoNotOptimize(c);
35+
for (std::size_t i = 0; i < SIZE; ++i) // same way to fill all container
36+
c[i] = 1; // not the most efficient for all
37+
auto indexer = []() {
38+
if constexpr (std::is_same_v<Order, RandomOrder>) {
39+
return [](const int i) {
40+
const unsigned i2 = i ^ 0x7777'7777;
41+
return (((i2 >> 16) + (i2 << 16)) % SIZE);
42+
};
43+
} else {
44+
static_assert(std::is_same_v<Order, InOrder>);
45+
return [](const int i) { return i; };
46+
}
47+
}();
48+
49+
for (auto _ : state) {
50+
int val = 0;
51+
for (int i = 0; i < COUNT; ++i) {
52+
if constexpr (std::is_same_v<Mode, UnsafeMode>) {
53+
val += c[indexer(i)];
54+
} else {
55+
static_assert(std::is_same_v<Mode, SafeMode>);
56+
val += c.at(indexer(i));
57+
}
58+
}
59+
benchmark::DoNotOptimize(val);
60+
benchmark::ClobberMemory();
61+
}
62+
}
63+
64+
#define ORDER RandomOrder // TODO Change me: InOrder or RandomOrder
65+
#define COMMA , // google benchmark macro does not support true comma
66+
BENCHMARK_TEMPLATE(bench, SafeMode, ORDER, DummyContainer)
67+
->Name("Do Nothing Reference");
68+
BENCHMARK_TEMPLATE(bench, UnsafeMode, ORDER, std::array<int COMMA SIZE>)
69+
->Name("array::operator[]");
70+
BENCHMARK_TEMPLATE(bench, SafeMode, ORDER, std::array<int COMMA SIZE>)
71+
->Name("array::at");
72+
BENCHMARK_TEMPLATE(bench, UnsafeMode, ORDER, std::vector<int>, SIZE)
73+
->Name("vector::operator[]");
74+
BENCHMARK_TEMPLATE(bench, SafeMode, ORDER, std::vector<int>, SIZE)
75+
->Name("vector::at");
76+
BENCHMARK_TEMPLATE(bench, UnsafeMode, ORDER, std::map<int COMMA int>)
77+
->Name("map::operator[]");
78+
BENCHMARK_TEMPLATE(bench, SafeMode, ORDER, std::map<int COMMA int>)
79+
->Name("map::at");
80+
BENCHMARK_TEMPLATE(bench, UnsafeMode, ORDER, std::unordered_map<int COMMA int>)
81+
->Name("unordered_map::operator[]");
82+
BENCHMARK_TEMPLATE(bench, SafeMode, ORDER, std::unordered_map<int COMMA int>)
83+
->Name("unordered_map::at");
84+
85+
BENCHMARK_MAIN();

Curiosity/map_hmap--benchmark.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include <cstdint>
22

33
#include <benchmark/benchmark.h>
4-
#include <ctime>
54
#include <map>
65
#include <random>
76
#include <unordered_map>

0 commit comments

Comments
 (0)