Skip to content

Commit 250e7cb

Browse files
authored
used lazy_emplace_with_hash instead of find/emplace (#206)
1 parent 1030bfa commit 250e7cb

File tree

4 files changed

+102
-10
lines changed

4 files changed

+102
-10
lines changed

pp/series_index/benchmarks/BUILD

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,14 @@ cc_binary(
88
"//:series_index",
99
"//:benchmark",
1010
],
11+
)
12+
13+
cc_binary(
14+
name = "find_or_emplace",
15+
srcs = ["find_or_emplace_benchmark.cpp"],
16+
malloc = "@jemalloc",
17+
deps = [
18+
"//:series_index",
19+
"//:benchmark",
20+
],
1121
)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include <benchmark/benchmark.h>
2+
3+
#include "primitives/snug_composites.h"
4+
#include "profiling/profiling.h"
5+
#include "series_index/queryable_encoding_bimap.h"
6+
#include "series_index/trie/cedarpp_tree.h"
7+
8+
namespace {
9+
10+
using QueryableEncodingBimap =
11+
series_index::QueryableEncodingBimap<PromPP::Primitives::SnugComposites::LabelSet::EncodingBimapFilament, BareBones::Vector, series_index::trie::CedarTrie>;
12+
13+
std::string_view get_lss_file() {
14+
if (auto& context = benchmark::internal::GetGlobalContext(); context != nullptr) {
15+
return context->operator[]("lss_file");
16+
}
17+
18+
return {};
19+
}
20+
21+
QueryableEncodingBimap& get_lss() {
22+
static QueryableEncodingBimap lss;
23+
if (lss.size() == 0) {
24+
std::ifstream infile(get_lss_file().data(), std::ios_base::binary);
25+
infile >> lss;
26+
}
27+
28+
return lss;
29+
}
30+
31+
void BenchmarkFindOrEmplaceWithEmplace(benchmark::State& state) {
32+
ZoneScoped;
33+
const auto& lss = get_lss();
34+
35+
for ([[maybe_unused]] auto _ : state) {
36+
QueryableEncodingBimap lss2;
37+
for (const auto& label_set : lss) {
38+
lss2.find_or_emplace(label_set);
39+
}
40+
}
41+
}
42+
43+
void BenchmarkFindOrEmplaceWithFind(benchmark::State& state) {
44+
ZoneScoped;
45+
auto& lss = get_lss();
46+
47+
for ([[maybe_unused]] auto _ : state) {
48+
for (const auto& label_set : lss) {
49+
lss.find_or_emplace(label_set);
50+
}
51+
}
52+
}
53+
54+
double min_value(const std::vector<double>& v) noexcept {
55+
return *std::ranges::min_element(v);
56+
}
57+
58+
BENCHMARK(BenchmarkFindOrEmplaceWithEmplace)->ComputeStatistics("min", min_value);
59+
BENCHMARK(BenchmarkFindOrEmplaceWithFind)->ComputeStatistics("min", min_value);
60+
61+
} // namespace

pp/series_index/queryable_encoding_bimap.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ class QueryableEncodingBimap final : public BareBones::SnugComposite::GenericDec
5050
template <class LabelSet>
5151
PROMPP_ALWAYS_INLINE uint32_t find_or_emplace(const LabelSet& label_set, size_t hash) noexcept {
5252
hash = phmap_hash(hash);
53-
if (auto it = ls_id_hash_set_.find(label_set, hash); it != ls_id_hash_set_.end()) {
54-
mark_series_as_added(*it);
55-
return *it;
56-
}
53+
const auto ls_id = *ls_id_hash_set_.lazy_emplace_with_hash(label_set, hash, [&](const auto& ctor) {
54+
auto new_ls_id = Base::items_.size();
55+
ctor(typename Base::Proxy(new_ls_id));
56+
auto composite_label_set = Base::items_.emplace_back(Base::data_, label_set).composite(Base::data());
57+
update_indexes(new_ls_id, composite_label_set);
58+
return new_ls_id;
59+
});
5760

58-
auto ls_id = Base::items_.size();
59-
auto composite_label_set = Base::items_.emplace_back(Base::data_, label_set).composite(Base::data());
60-
update_indexes(ls_id, composite_label_set, hash);
6161
mark_series_as_added(ls_id);
6262
return ls_id;
6363
}
@@ -107,12 +107,12 @@ class QueryableEncodingBimap final : public BareBones::SnugComposite::GenericDec
107107
const auto hasher = Base::hasher();
108108
for (auto ls_id = first_loaded_id; ls_id < Base::items_.size(); ++ls_id) {
109109
auto label_set = this->operator[](ls_id);
110-
update_indexes(ls_id, label_set, phmap_hash(hasher(label_set)));
110+
ls_id_hash_set_.emplace_with_hash(phmap_hash(hasher(label_set)), typename Base::Proxy(ls_id));
111+
update_indexes(ls_id, label_set);
111112
}
112113
}
113114

114-
void update_indexes(uint32_t ls_id, const LabelSet& label_set, size_t label_set_phmap_hash) {
115-
ls_id_hash_set_.emplace_with_hash(label_set_phmap_hash, typename Base::Proxy(ls_id));
115+
void update_indexes(uint32_t ls_id, const LabelSet& label_set) {
116116
auto ls_id_set_iterator = ls_id_set_.emplace(ls_id).first;
117117

118118
for (auto label = label_set.begin(); label != label_set.end(); ++label) {

pp/series_index/tests/queryable_encoding_bimap_tests.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,27 @@ TEST_F(QueryableEncodingBimapFixture, EmplaceDuplicatedLabelSet) {
119119
EXPECT_NE(ls_id1, ls_id2);
120120
}
121121

122+
TEST_F(QueryableEncodingBimapFixture, Load) {
123+
// Arrange
124+
const auto label_set1 = LabelViewSet{{"job", "cron"}, {"key", ""}, {"process", "php"}};
125+
const auto label_set2 = LabelViewSet{{"job", "cron"}, {"key", ""}, {"process", "php1"}};
126+
127+
const auto ls_id1 = lss_.find_or_emplace(label_set1);
128+
const auto ls_id2 = lss_.find_or_emplace(label_set2);
129+
130+
std::stringstream stream;
131+
stream << lss_;
132+
133+
Lss lss2;
134+
135+
// Act
136+
stream >> lss2;
137+
138+
// Assert
139+
EXPECT_EQ(ls_id1, lss2.find(label_set1));
140+
EXPECT_EQ(ls_id2, lss2.find(label_set2));
141+
}
142+
122143
class QueryableEncodingBimapCopierFixture : public QueryableEncodingBimapFixture {
123144
protected:
124145
BareBones::Vector<uint32_t> dst_src_ids_mapping_;

0 commit comments

Comments
 (0)