4d2eda398f
Summary: This diff improves the performance of `PropertyStore` with two main techniques: First: `PropertyValue` has a very expensive constructor and destructor. The `PropertyValue` was previously passed as a return value from many functions wrapped in a `std::optional`. That caused the `PropertyValue` constructor/destructor to be called for each intermediary value that was passed between functions. This diff changes the functions to return a `bool` value that imitates the `std::optional` "emptyness" flag and the `PropertyValue` is modified using a pointer to it so that its constructor/destructor is called only once. Second: The `PropertyStore` buffer was previously iterated through at least twice. First to determine the exact position of the encoded property and then to actually decode the property. This diff combines the two passes into a single pass so that the property is immediately loaded if it is found. Reviewers: buda Reviewed By: buda Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2766
115 lines
3.5 KiB
C++
115 lines
3.5 KiB
C++
#include <chrono>
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <random>
|
|
|
|
#include <benchmark/benchmark.h>
|
|
|
|
#include "storage/v2/property_store.hpp"
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// PropertyStore Set
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// NOLINTNEXTLINE(google-runtime-references)
|
|
static void PropertyStoreSet(benchmark::State &state) {
|
|
storage::PropertyStore store;
|
|
std::mt19937 gen(state.thread_index);
|
|
std::uniform_int_distribution<uint64_t> dist(0, state.range(0) - 1);
|
|
uint64_t counter = 0;
|
|
while (state.KeepRunning()) {
|
|
auto prop = storage::PropertyId::FromUint(dist(gen));
|
|
store.SetProperty(prop, storage::PropertyValue(42));
|
|
++counter;
|
|
}
|
|
state.SetItemsProcessed(counter);
|
|
}
|
|
|
|
BENCHMARK(PropertyStoreSet)
|
|
->RangeMultiplier(2)
|
|
->Range(1, 1024)
|
|
->Unit(benchmark::kNanosecond)
|
|
->UseRealTime();
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// std::map Set
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// NOLINTNEXTLINE(google-runtime-references)
|
|
static void StdMapSet(benchmark::State &state) {
|
|
std::map<storage::PropertyId, storage::PropertyValue> store;
|
|
std::mt19937 gen(state.thread_index);
|
|
std::uniform_int_distribution<uint64_t> dist(0, state.range(0) - 1);
|
|
uint64_t counter = 0;
|
|
while (state.KeepRunning()) {
|
|
auto prop = storage::PropertyId::FromUint(dist(gen));
|
|
store.emplace(prop, storage::PropertyValue(42));
|
|
++counter;
|
|
}
|
|
state.SetItemsProcessed(counter);
|
|
}
|
|
|
|
BENCHMARK(StdMapSet)
|
|
->RangeMultiplier(2)
|
|
->Range(1, 1024)
|
|
->Unit(benchmark::kNanosecond)
|
|
->UseRealTime();
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// PropertyStore Get
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// NOLINTNEXTLINE(google-runtime-references)
|
|
static void PropertyStoreGet(benchmark::State &state) {
|
|
storage::PropertyStore store;
|
|
for (uint64_t i = 0; i < state.range(0); ++i) {
|
|
auto prop = storage::PropertyId::FromUint(i);
|
|
store.SetProperty(prop, storage::PropertyValue(0));
|
|
}
|
|
std::mt19937 gen(state.thread_index);
|
|
std::uniform_int_distribution<uint64_t> dist(0, state.range(0) - 1);
|
|
uint64_t counter = 0;
|
|
while (state.KeepRunning()) {
|
|
auto prop = storage::PropertyId::FromUint(dist(gen));
|
|
store.GetProperty(prop);
|
|
++counter;
|
|
}
|
|
state.SetItemsProcessed(counter);
|
|
}
|
|
|
|
BENCHMARK(PropertyStoreGet)
|
|
->RangeMultiplier(2)
|
|
->Range(1, 1024)
|
|
->Unit(benchmark::kNanosecond)
|
|
->UseRealTime();
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// std::map Get
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// NOLINTNEXTLINE(google-runtime-references)
|
|
static void StdMapGet(benchmark::State &state) {
|
|
std::map<storage::PropertyId, storage::PropertyValue> store;
|
|
for (uint64_t i = 0; i < state.range(0); ++i) {
|
|
auto prop = storage::PropertyId::FromUint(i);
|
|
store.emplace(prop, storage::PropertyValue(0));
|
|
}
|
|
std::mt19937 gen(state.thread_index);
|
|
std::uniform_int_distribution<uint64_t> dist(0, state.range(0) - 1);
|
|
uint64_t counter = 0;
|
|
while (state.KeepRunning()) {
|
|
auto prop = storage::PropertyId::FromUint(dist(gen));
|
|
store.find(prop);
|
|
++counter;
|
|
}
|
|
state.SetItemsProcessed(counter);
|
|
}
|
|
|
|
BENCHMARK(StdMapGet)
|
|
->RangeMultiplier(2)
|
|
->Range(1, 1024)
|
|
->Unit(benchmark::kNanosecond)
|
|
->UseRealTime();
|
|
|
|
BENCHMARK_MAIN();
|