Use MemoryResource in UnwindCursor

Summary:
Micro benchmarks show no change compared to global new & delete. This is
to be expected, because Unwind relies only on `std::vector` which ought
to reserve the memory in reasonable chunks.

Reviewers: mtomic, llugovic

Reviewed By: mtomic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D2064
This commit is contained in:
Teon Banek 2019-05-17 10:16:42 +02:00
parent 880f23620d
commit 4f4837392e
2 changed files with 48 additions and 4 deletions
src/query/plan
tests/benchmark/query

View File

@ -3140,7 +3140,8 @@ class UnwindCursor : public Cursor {
utils::MemoryResource *mem)
: self_(self),
db_(*db),
input_cursor_(self.input_->MakeCursor(db, mem)) {}
input_cursor_(self.input_->MakeCursor(db, mem)),
input_value_(mem) {}
bool Pull(Frame &frame, ExecutionContext &context) override {
SCOPED_PROFILE_OP("Unwind");
@ -3161,7 +3162,12 @@ class UnwindCursor : public Cursor {
throw QueryRuntimeException(
"Argument of UNWIND must be a list, but '{}' was provided.",
input_value.type());
input_value_ = input_value.Value<std::vector<TypedValue>>();
// Copy the evaluted input_value_list to our vector. Since we use a
// different allocator, we cannot just do
// input_value_ = input_value.ValueList();
const auto &input_value_list = input_value.ValueList();
input_value_.reserve(input_value_list.size());
input_value_.assign(input_value_list.begin(), input_value_list.end());
input_value_it_ = input_value_.begin();
}
@ -3186,9 +3192,9 @@ class UnwindCursor : public Cursor {
database::GraphDbAccessor &db_;
const UniqueCursorPtr input_cursor_;
// typed values we are unwinding and yielding
std::vector<TypedValue> input_value_;
std::vector<TypedValue, utils::Allocator<TypedValue>> input_value_;
// current position in input_value_
std::vector<TypedValue>::iterator input_value_it_ = input_value_.end();
decltype(input_value_)::iterator input_value_it_ = input_value_.end();
};
UniqueCursorPtr Unwind::MakeCursor(database::GraphDbAccessor *db,

View File

@ -387,4 +387,42 @@ BENCHMARK_TEMPLATE(OrderBy, MonotonicBufferResource)
->Ranges({{4, 1U << 7U}, {512, 1U << 13U}})
->Unit(benchmark::kMicrosecond);
template <class TMemory>
// NOLINTNEXTLINE(google-runtime-references)
static void Unwind(benchmark::State &state) {
query::AstStorage ast;
query::Parameters parameters;
database::GraphDb db;
AddVertices(&db, state.range(0));
query::SymbolTable symbol_table;
auto scan_all = std::make_shared<query::plan::ScanAll>(
nullptr, symbol_table.CreateSymbol("v", false));
auto list_sym = symbol_table.CreateSymbol("list", false);
auto *list_expr = ast.Create<query::Identifier>("list")->MapTo(list_sym);
auto out_sym = symbol_table.CreateSymbol("out", false);
query::plan::Unwind unwind(scan_all, list_expr, out_sym);
auto dba = db.Access();
query::Frame frame(symbol_table.max_position());
frame[list_sym] = std::vector<query::TypedValue>(state.range(1));
// Nothing should be used from the EvaluationContext, so leave it empty.
query::EvaluationContext evaluation_context;
while (state.KeepRunning()) {
query::ExecutionContext execution_context{&dba, symbol_table,
evaluation_context};
TMemory memory;
auto cursor = unwind.MakeCursor(&dba, memory.get());
while (cursor->Pull(frame, execution_context))
;
}
state.SetItemsProcessed(state.iterations());
}
BENCHMARK_TEMPLATE(Unwind, NewDeleteResource)
->Ranges({{4, 1U << 7U}, {512, 1U << 13U}})
->Unit(benchmark::kMicrosecond);
BENCHMARK_TEMPLATE(Unwind, MonotonicBufferResource)
->Ranges({{4, 1U << 7U}, {512, 1U << 13U}})
->Unit(benchmark::kMicrosecond);
BENCHMARK_MAIN();