Merge branch 'dev' of https://memgraph.phacility.com/diffusion/MG/memgraph into dev
This commit is contained in:
commit
e46c1cd848
75
include/utils/random/generator.h
Normal file
75
include/utils/random/generator.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include <random>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// namespace ::utils
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
// namespace utils::random
|
||||||
|
namespace random {
|
||||||
|
|
||||||
|
template <class Distribution, class Generator>
|
||||||
|
class RandomGenerator {
|
||||||
|
private:
|
||||||
|
std::random_device device_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Generator gen_;
|
||||||
|
Distribution dist_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RandomGenerator(Distribution dist) : gen_(device_()), dist_(dist) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class StringGenerator
|
||||||
|
: public RandomGenerator<std::uniform_int_distribution<int>,
|
||||||
|
std::default_random_engine> {
|
||||||
|
private:
|
||||||
|
int size_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
StringGenerator(int size)
|
||||||
|
: RandomGenerator(std::uniform_int_distribution<int>(32, 126)),
|
||||||
|
size_(size) {}
|
||||||
|
|
||||||
|
std::string next(int size) {
|
||||||
|
std::string random_string;
|
||||||
|
random_string.reserve(size);
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) random_string += (dist_(gen_) + '\0');
|
||||||
|
|
||||||
|
return random_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string next() { return next(size_); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Distribution, class Generator, class DistributionRangeType>
|
||||||
|
class NumberGenerator : public RandomGenerator<Distribution, Generator> {
|
||||||
|
public:
|
||||||
|
NumberGenerator(DistributionRangeType start, DistributionRangeType end)
|
||||||
|
: RandomGenerator<Distribution, Generator>(Distribution(start, end)) {}
|
||||||
|
|
||||||
|
auto next() { return this->dist_(this->gen_); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class FirstGenerator, class SecondGenerator>
|
||||||
|
class PairGenerator {
|
||||||
|
private:
|
||||||
|
FirstGenerator *first_;
|
||||||
|
SecondGenerator *second_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PairGenerator(FirstGenerator *first, SecondGenerator *second)
|
||||||
|
: first_(first), second_(second) {}
|
||||||
|
auto next() { return std::make_pair(first_->next(), second_->next()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class RandomGenerator>
|
||||||
|
auto generate_vector(RandomGenerator &gen, int size) {
|
||||||
|
std::vector<decltype(gen.next())> elements(size);
|
||||||
|
for (int i = 0; i < size; i++) elements[i] = gen.next();
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace utils::random
|
||||||
|
}; // namespace ::utils
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
#include <ratio>
|
#include <ratio>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@ foreach(ONE_BENCH_CPP ${ALL_BENCH_CPP})
|
|||||||
add_executable(${TARGET_NAME} ${ONE_BENCH_CPP})
|
add_executable(${TARGET_NAME} ${ONE_BENCH_CPP})
|
||||||
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${ONE_BENCH_EXEC})
|
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${ONE_BENCH_EXEC})
|
||||||
target_link_libraries(${TARGET_NAME} benchmark ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(${TARGET_NAME} benchmark ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
target_link_libraries(${TARGET_NAME} memgraph)
|
||||||
|
target_link_libraries(${TARGET_NAME} ${fmt_static_lib})
|
||||||
|
target_link_libraries(${TARGET_NAME} Threads::Threads)
|
||||||
|
target_link_libraries(${TARGET_NAME} ${yaml_static_lib})
|
||||||
add_test(${TARGET_NAME} ${ONE_BENCH_EXEC})
|
add_test(${TARGET_NAME} ${ONE_BENCH_EXEC})
|
||||||
|
|
||||||
endforeach()
|
endforeach()
|
||||||
|
221
tests/benchmark/data_structures/concurrent/concurrent_map.cpp
Normal file
221
tests/benchmark/data_structures/concurrent/concurrent_map.cpp
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
#include <random>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "data_structures/concurrent/concurrent_map.hpp"
|
||||||
|
#include "logging/default.hpp"
|
||||||
|
#include "logging/streams/stdout.hpp"
|
||||||
|
#include "utils/random/generator.h"
|
||||||
|
|
||||||
|
#include "benchmark/benchmark_api.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
ConcurrentMap Benchmark Test:
|
||||||
|
- tests time of Insertion, Contain and Delete operations
|
||||||
|
|
||||||
|
- benchmarking time per operation
|
||||||
|
|
||||||
|
- test run ConcurrentMap with the following keys and values:
|
||||||
|
- <int,int>
|
||||||
|
- <int, string>
|
||||||
|
- <string, int>
|
||||||
|
- <string, string>
|
||||||
|
|
||||||
|
- tests run single and multi threaded in range (1, Max_Threads_Per_Cpu)
|
||||||
|
|
||||||
|
TODO(sale) implements configurable command line arguments on start
|
||||||
|
*/
|
||||||
|
|
||||||
|
using utils::random::NumberGenerator;
|
||||||
|
using utils::random::PairGenerator;
|
||||||
|
using utils::random::StringGenerator;
|
||||||
|
|
||||||
|
using IntegerGenerator = NumberGenerator<std::uniform_int_distribution<int>,
|
||||||
|
std::default_random_engine, int>;
|
||||||
|
|
||||||
|
template <class K, class V>
|
||||||
|
static void InsertValue(benchmark::State& state, ConcurrentMap<K, V>* map,
|
||||||
|
const std::vector<std::pair<K, V>>& elements) {
|
||||||
|
while (state.KeepRunning()) {
|
||||||
|
auto accessor = map->access();
|
||||||
|
for (int start = 0; start < state.range(0); start++) {
|
||||||
|
accessor.insert(elements[start].first, elements[start].second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.SetComplexityN(state.range(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K, class V>
|
||||||
|
static void DeleteValue(benchmark::State& state, ConcurrentMap<K, V>* map,
|
||||||
|
const std::vector<std::pair<K, V>> elements) {
|
||||||
|
while (state.KeepRunning()) {
|
||||||
|
auto accessor = map->access();
|
||||||
|
for (int start = 0; start < state.range(0); start++) {
|
||||||
|
accessor.remove(elements[start].first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.SetComplexityN(state.range(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K, class V>
|
||||||
|
static void ContainsValue(benchmark::State& state, ConcurrentMap<K, V>* map,
|
||||||
|
const std::vector<std::pair<K, V>> elements) {
|
||||||
|
while (state.KeepRunning()) {
|
||||||
|
auto accessor = map->access();
|
||||||
|
for (int start = 0; start < state.range(0); start++) {
|
||||||
|
accessor.contains(elements[start].first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.SetComplexityN(state.range(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto BM_InsertValue = [](benchmark::State& state, auto* map, auto& elements) {
|
||||||
|
InsertValue(state, map, elements);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto BM_DeleteValue = [](benchmark::State& state, auto* map, auto elements) {
|
||||||
|
DeleteValue(state, map, elements);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto BM_ContainsValue = [](benchmark::State& state, auto* map, auto elements) {
|
||||||
|
ContainsValue(state, map, elements);
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
int MAX_ELEMENTS = 1 << 14;
|
||||||
|
int MULTIPLIER = 2;
|
||||||
|
int MAX_THREADS = (int)std::thread::hardware_concurrency();
|
||||||
|
|
||||||
|
logging::init_async();
|
||||||
|
logging::log->pipe(std::make_unique<Stdout>());
|
||||||
|
|
||||||
|
StringGenerator sg(128);
|
||||||
|
IntegerGenerator ig(0, 1000000);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Creates RandomGenerators, ConcurentMaps and Random Element Vectors for the
|
||||||
|
following use cases:
|
||||||
|
|
||||||
|
Map elements contain keys and value for:
|
||||||
|
<int, int>,
|
||||||
|
<int, string>
|
||||||
|
<string, int>
|
||||||
|
<string, string>
|
||||||
|
*/
|
||||||
|
|
||||||
|
PairGenerator<IntegerGenerator, IntegerGenerator> piig(&ig, &ig);
|
||||||
|
PairGenerator<StringGenerator, StringGenerator> pssg(&sg, &sg);
|
||||||
|
PairGenerator<StringGenerator, IntegerGenerator> psig(&sg, &ig);
|
||||||
|
PairGenerator<IntegerGenerator, StringGenerator> pisg(&ig, &sg);
|
||||||
|
|
||||||
|
ConcurrentMap<int, int> ii_map;
|
||||||
|
ConcurrentMap<int, std::string> is_map;
|
||||||
|
ConcurrentMap<std::string, int> si_map;
|
||||||
|
ConcurrentMap<std::string, std::string> ss_map;
|
||||||
|
|
||||||
|
auto ii_elems = utils::random::generate_vector(piig, MAX_ELEMENTS);
|
||||||
|
auto is_elems = utils::random::generate_vector(pisg, MAX_ELEMENTS);
|
||||||
|
auto si_elems = utils::random::generate_vector(psig, MAX_ELEMENTS);
|
||||||
|
auto ss_elems = utils::random::generate_vector(pssg, MAX_ELEMENTS);
|
||||||
|
|
||||||
|
/* insertion Tests */
|
||||||
|
|
||||||
|
for (int t = 1; t <= MAX_THREADS; t *= 2) {
|
||||||
|
benchmark::RegisterBenchmark("InsertValue[Int, Int]", BM_InsertValue,
|
||||||
|
&ii_map, ii_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
|
||||||
|
benchmark::RegisterBenchmark("InsertValue[Int, String] (size:128 chars)",
|
||||||
|
BM_InsertValue, &is_map, is_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
|
||||||
|
benchmark::RegisterBenchmark("InsertValue[String, Int] (size:128 chars)",
|
||||||
|
BM_InsertValue, &si_map, si_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
|
||||||
|
benchmark::RegisterBenchmark("InsertValue[String, String] (size:128 chars)",
|
||||||
|
BM_InsertValue, &ss_map, ss_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contains Benchmark Tests
|
||||||
|
|
||||||
|
for (int t = 1; t <= MAX_THREADS; t *= 2) {
|
||||||
|
benchmark::RegisterBenchmark("ContainsValue[Int, Int]", BM_ContainsValue,
|
||||||
|
&ii_map, ii_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
|
||||||
|
benchmark::RegisterBenchmark("ContainsValue[Int, String] (size:128 chars)",
|
||||||
|
BM_ContainsValue, &is_map, is_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
|
||||||
|
benchmark::RegisterBenchmark("ContainsValue[String, Int] (size:128 chars)",
|
||||||
|
BM_ContainsValue, &si_map, si_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
|
||||||
|
benchmark::RegisterBenchmark(
|
||||||
|
"ContainsValue[String, String] (size:128 chars)", BM_ContainsValue,
|
||||||
|
&ss_map, ss_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deletion Banchamark Tests
|
||||||
|
|
||||||
|
for (int t = 1; t <= MAX_THREADS; t *= 2) {
|
||||||
|
benchmark::RegisterBenchmark("DeleteValue[Int, Int]", BM_DeleteValue,
|
||||||
|
&ii_map, ii_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
|
||||||
|
benchmark::RegisterBenchmark("DeleteValue[Int, String] (size:128 chars)",
|
||||||
|
BM_DeleteValue, &is_map, is_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
|
||||||
|
benchmark::RegisterBenchmark("DeleteValue[String, Int] (size:128 chars)",
|
||||||
|
BM_DeleteValue, &si_map, si_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
|
||||||
|
benchmark::RegisterBenchmark("DeleteValue[String, String] (size:128 chars)",
|
||||||
|
BM_DeleteValue, &ss_map, ss_elems)
|
||||||
|
->RangeMultiplier(MULTIPLIER)
|
||||||
|
->Range(1, MAX_ELEMENTS)
|
||||||
|
->Complexity(benchmark::oN)
|
||||||
|
->Threads(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark::Initialize(&argc, argv);
|
||||||
|
benchmark::RunSpecifiedBenchmarks();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
44
tests/benchmark/query/strip/stripper.cpp
Normal file
44
tests/benchmark/query/strip/stripper.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "logging/default.hpp"
|
||||||
|
#include "logging/streams/stdout.hpp"
|
||||||
|
#include "utils/time/timer.hpp"
|
||||||
|
#include "query/preprocesor.hpp"
|
||||||
|
|
||||||
|
#include "benchmark/benchmark_api.h"
|
||||||
|
#include "yaml-cpp/yaml.h"
|
||||||
|
|
||||||
|
auto BM_Strip = [](benchmark::State& state, auto& function, std::string query) {
|
||||||
|
while (state.KeepRunning()) {
|
||||||
|
for (int start = 0; start < state.range(0); start++) {
|
||||||
|
function(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.SetComplexityN(state.range(0));
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
logging::init_async();
|
||||||
|
logging::log->pipe(std::make_unique<Stdout>());
|
||||||
|
|
||||||
|
YAML::Node dataset = YAML::LoadFile(
|
||||||
|
"../../tests/data/cypher_queries/stripper/query_dict.yaml");
|
||||||
|
|
||||||
|
QueryPreprocessor processor;
|
||||||
|
using std::placeholders::_1;
|
||||||
|
std::function<QueryStripped(const std::string& query)> preprocess =
|
||||||
|
std::bind(&QueryPreprocessor::preprocess, &processor, _1);
|
||||||
|
|
||||||
|
auto tests = dataset["benchmark_queries"].as<std::vector<std::string>>();
|
||||||
|
for (auto& test : tests) {
|
||||||
|
auto* benchmark =
|
||||||
|
benchmark::RegisterBenchmark(test.c_str(), BM_Strip, preprocess, test)
|
||||||
|
->RangeMultiplier(2)
|
||||||
|
->Range(1, 8 << 10)
|
||||||
|
->Complexity(benchmark::oN);
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark::Initialize(&argc, argv);
|
||||||
|
benchmark::RunSpecifiedBenchmarks();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
42
tests/data/cypher_queries/stripper/query_dict.yaml
Normal file
42
tests/data/cypher_queries/stripper/query_dict.yaml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
benchmark_queries:
|
||||||
|
- "MATCH (a) RETURN size(collect(a))"
|
||||||
|
|
||||||
|
- "CREATE (a:L), (b1), (b2) CREATE (a)-[:A]->(b1), (a)-[:A]->(b2)"
|
||||||
|
|
||||||
|
- "MATCH (a:L)-[rel]->(b) RETURN a, count(*)"
|
||||||
|
|
||||||
|
- "CREATE ({division: 'Sweden'})"
|
||||||
|
|
||||||
|
- "MATCH (n) RETURN n.division, count(*) ORDER BY count(*) DESC, n.division ASC"
|
||||||
|
|
||||||
|
- "UNWIND ['a', 'b', 'B', null, 'abc', 'abc1'] AS i RETURN max(i)"
|
||||||
|
|
||||||
|
- "CREATE ({created: true})"
|
||||||
|
|
||||||
|
- "MATCH (a)-[r]-(b) DELETE r, a, b RETURN count(*) AS c"
|
||||||
|
|
||||||
|
- "MATCH (u:User) WITH {key: u} AS nodes DELETE nodes.key"
|
||||||
|
|
||||||
|
- "CREATE ()-[:T {id: 42, alive: true, name: kifla, height=4.2}]->()"
|
||||||
|
|
||||||
|
- "MATCH p = ()-[r:T]-() WHERE r.id = 42 DELETE r"
|
||||||
|
|
||||||
|
- "UNWIND range(0, 1000) AS i CREATE (:A {id: i}) MERGE (:B {id: i % 10})"
|
||||||
|
|
||||||
|
- "MATCH (n) WHERE NOT(n.name = 'apa' AND false) RETURN n"
|
||||||
|
|
||||||
|
- "CREATE ()-[:REL {property1: 12, property2: 24}]->()"
|
||||||
|
|
||||||
|
- "MATCH (n:A) WHERE n.name = 'Andres' SET n.name = 'Michael' RETURN n"
|
||||||
|
|
||||||
|
- "MATCH (n:A) SET (n).name = 'memgraph' RETURN n"
|
||||||
|
|
||||||
|
- "CREATE (a {foo: [1, 2, 3]}) SET a.foo = a.foo + [4, 5] RETURN a.foo"
|
||||||
|
|
||||||
|
- "MATCH (n:X {foo: 'A'}) SET n = {foo: 'B', baz: 'C'} RETURN n"
|
||||||
|
|
||||||
|
- "MATCH (n:X {foo: 'A'}) SET n += {foo: null} RETURN n"
|
||||||
|
|
||||||
|
- "MATCH (n) WITH n LIMIT toInteger(ceil(1.7)) RETURN count(*) AS count"
|
||||||
|
|
||||||
|
- "MATCH (a:A), (b:B) MERGE (a)-[r:TYPE]->(b) ON CREATE SET r.name = 'Lola' RETURN count(r)"
|
Loading…
Reference in New Issue
Block a user