memgraph/tests/benchmark/query/eval.cpp
Teon Banek 88de3422d0 Use stack allocation for cypher function arguments
Summary:
This is a simple change which modifies interface of
awesome_memgraph_functions to accept C-style pointer to array with
count. Doing things this way, allows us to easily try out different
allocation schemes for function arguments. In this diff, we are now
using stack allocation of arguments in a plain fixed size array. This is
done when the number of arguments is small. According to heaptrack, this
small change should yield noticeable improvements to heap usage.

Obviously, this doesn't solve the problem of heap allocations inside
TypedValue arguments themselves. These allocations appear when
std::string and std::vector is used inside TypedValue.

Micro benchmarks show that there is some performance improvement,
mostly around the limits of using array vs std::vector. The improvement is
more noticeable with multiple threads, due to primary gain being in avoiding
calls to memory allocation.

Reviewers: mtomic, msantl, mferencevic

Reviewed By: mferencevic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1581
2018-09-03 11:23:29 +02:00

56 lines
1.8 KiB
C++

#include <benchmark/benchmark.h>
#include "query/frontend/ast/ast.hpp"
#include "query/interpret/eval.hpp"
static void BenchmarkCoalesceCallWithNulls(benchmark::State &state) {
int64_t num_args = state.range(0);
query::AstStorage ast_storage;
std::vector<query::Expression *> arguments;
arguments.reserve(num_args);
for (int64_t i = 0; i < num_args; ++i) {
arguments.emplace_back(
ast_storage.Create<query::PrimitiveLiteral>(query::TypedValue::Null));
}
auto *function = ast_storage.Create<query::Function>("COALESCE", arguments);
query::Frame frame(0);
database::GraphDbAccessor *dba = nullptr;
query::Context context(*dba);
query::ExpressionEvaluator evaluator(frame, &context, query::GraphView::OLD);
while (state.KeepRunning()) {
function->Accept(evaluator);
}
}
static void BenchmarkCoalesceCallWithStrings(benchmark::State &state) {
int64_t num_args = state.range(0);
query::AstStorage ast_storage;
std::vector<query::Expression *> arguments;
arguments.reserve(num_args);
for (int64_t i = 0; i < num_args; ++i) {
std::string val = "some_string " + std::to_string(i);
arguments.emplace_back(ast_storage.Create<query::PrimitiveLiteral>(val));
}
auto *function = ast_storage.Create<query::Function>("COALESCE", arguments);
query::Frame frame(0);
database::GraphDbAccessor *dba = nullptr;
query::Context context(*dba);
query::ExpressionEvaluator evaluator(frame, &context, query::GraphView::OLD);
while (state.KeepRunning()) {
function->Accept(evaluator);
}
}
// We are interested in benchmarking the usual amount of arguments
BENCHMARK(BenchmarkCoalesceCallWithNulls)
->RangeMultiplier(2)
->Range(1, 256)
->ThreadRange(1, 16);
BENCHMARK(BenchmarkCoalesceCallWithStrings)
->RangeMultiplier(2)
->Range(1, 256)
->ThreadRange(1, 16);
BENCHMARK_MAIN();