Skip to content

Commit d207beb

Browse files
committed
Use std::less<> for Labels to enable heterogeneous lookup on C++14+
1 parent 0a779ab commit d207beb

3 files changed

Lines changed: 78 additions & 0 deletions

File tree

core/benchmarks/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ add_executable(benchmarks
77
gauge_bench.cc
88
histogram_bench.cc
99
info_bench.cc
10+
labels_bench.cc
1011
registry_bench.cc
1112
summary_bench.cc
1213
)

core/benchmarks/labels_bench.cc

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#include <benchmark/benchmark.h>
2+
3+
#include <functional>
4+
#include <map>
5+
#include <string>
6+
#include <utility>
7+
#include <vector>
8+
9+
#include "benchmark_helpers.h"
10+
11+
#if defined(__cpp_lib_string_view) && defined(__cpp_lib_generic_associative_lookup)
12+
#include <string_view>
13+
14+
using Plain = std::map<std::string, std::string>;
15+
using Transparent = std::map<std::string, std::string, std::less<>>;
16+
17+
template <typename Map>
18+
static Map MakeMap(std::size_t size, std::size_t key_length,
19+
std::vector<std::string>& keys) {
20+
Map map;
21+
keys.reserve(size);
22+
for (std::size_t i = 0; i < size; ++i) {
23+
auto key = GenerateRandomString(key_length);
24+
map.emplace(key, "value");
25+
keys.push_back(std::move(key));
26+
}
27+
return map;
28+
}
29+
30+
template <typename Map, bool Heterogeneous>
31+
static void BM_Labels_LookupView(benchmark::State& state) {
32+
std::vector<std::string> keys;
33+
const auto map = MakeMap<Map>(state.range(0), state.range(1), keys);
34+
std::size_t i = 0;
35+
while (state.KeepRunning()) {
36+
const std::string_view key = keys[i];
37+
if (++i == keys.size()) i = 0;
38+
if constexpr (Heterogeneous) {
39+
benchmark::DoNotOptimize(map.find(key));
40+
} else {
41+
benchmark::DoNotOptimize(map.find(std::string(key)));
42+
}
43+
}
44+
}
45+
46+
template <typename Map>
47+
static void BM_Labels_LookupString(benchmark::State& state) {
48+
std::vector<std::string> keys;
49+
const auto map = MakeMap<Map>(state.range(0), state.range(1), keys);
50+
std::size_t i = 0;
51+
while (state.KeepRunning()) {
52+
const std::string& key = keys[i];
53+
if (++i == keys.size()) i = 0;
54+
benchmark::DoNotOptimize(map.find(key));
55+
}
56+
}
57+
58+
BENCHMARK_TEMPLATE(BM_Labels_LookupView, Plain, false)
59+
->ArgsProduct({{4, 16}, {8, 32}});
60+
BENCHMARK_TEMPLATE(BM_Labels_LookupView, Transparent, true)
61+
->ArgsProduct({{4, 16}, {8, 32}});
62+
BENCHMARK_TEMPLATE(BM_Labels_LookupString, Plain)
63+
->ArgsProduct({{4, 16}, {8, 32}});
64+
BENCHMARK_TEMPLATE(BM_Labels_LookupString, Transparent)
65+
->ArgsProduct({{4, 16}, {8, 32}});
66+
67+
#endif

core/include/prometheus/labels.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
#pragma once
22

3+
#if defined(__cpp_lib_generic_associative_lookup)
4+
#include <functional>
5+
#endif
36
#include <map>
47
#include <string>
58

69
namespace prometheus {
710

811
/// \brief Multiple labels and their value.
12+
///
13+
/// Uses the transparent comparator std::less<> on C++14 and newer to allow
14+
/// heterogeneous lookup, falling back to the default comparator on C++11.
15+
#if defined(__cpp_lib_generic_associative_lookup)
16+
using Labels = std::map<std::string, std::string, std::less<>>;
17+
#else
918
using Labels = std::map<std::string, std::string>;
19+
#endif
1020

1121
/// \brief Single label and its value.
1222
using Label = Labels::value_type;

0 commit comments

Comments
 (0)