diff options
author | Hana Pearlman <hana.pearlman@mongodb.com> | 2022-11-02 18:18:44 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-11-02 19:05:58 +0000 |
commit | ea4fa8178b52d17a61d5104543890a5f5079f5f6 (patch) | |
tree | 412a6ff343a203b255848b90b563e15c75286a21 | |
parent | d2fb5646942d989da1819e49ec2ab924927fa270 (diff) | |
download | mongo-ea4fa8178b52d17a61d5104543890a5f5079f5f6.tar.gz |
SERVER-62033: Add C++ performance benchmarks for ABT translation
-rw-r--r-- | buildscripts/resmokeconfig/suites/benchmarks.yml | 2 | ||||
-rw-r--r-- | buildscripts/resmokeconfig/suites/benchmarks_abt.yml | 14 | ||||
-rw-r--r-- | etc/evergreen_yml_components/definitions.yml | 12 | ||||
-rw-r--r-- | src/mongo/db/pipeline/SConscript | 16 | ||||
-rw-r--r-- | src/mongo/db/pipeline/abt/abt_translate_bm_fixture.cpp | 211 | ||||
-rw-r--r-- | src/mongo/db/pipeline/abt/abt_translate_bm_fixture.h | 137 | ||||
-rw-r--r-- | src/mongo/db/pipeline/abt/abt_translate_cq_bm.cpp | 88 | ||||
-rw-r--r-- | src/mongo/db/pipeline/abt/abt_translate_pipeline_bm.cpp | 90 |
8 files changed, 570 insertions, 0 deletions
diff --git a/buildscripts/resmokeconfig/suites/benchmarks.yml b/buildscripts/resmokeconfig/suites/benchmarks.yml index e4cb3c6b7aa..a0bc6668cec 100644 --- a/buildscripts/resmokeconfig/suites/benchmarks.yml +++ b/buildscripts/resmokeconfig/suites/benchmarks.yml @@ -21,6 +21,8 @@ selector: # These benchmarks are being run as part of the benchmarks_expression*.yml - build/install/bin/expression_bm* - build/install/bin/sbe_expression_bm* + # These benchmarks are being run as part of the benchmarks_abt.yml test suite. + - build/install/bin/abt_translation_bm* executor: diff --git a/buildscripts/resmokeconfig/suites/benchmarks_abt.yml b/buildscripts/resmokeconfig/suites/benchmarks_abt.yml new file mode 100644 index 00000000000..74149aaa2d2 --- /dev/null +++ b/buildscripts/resmokeconfig/suites/benchmarks_abt.yml @@ -0,0 +1,14 @@ +# This benchmark measures the performance of ABT translation. +test_kind: benchmark_test + +selector: + root: build/benchmarks.txt + include_files: + # The trailing asterisk is for handling the .exe extension on Windows. + - build/**/system_resource_canary_bm* + - build/install/bin/abt_translation_bm* + +executor: + config: {} + hooks: + - class: CombineBenchmarkResults diff --git a/etc/evergreen_yml_components/definitions.yml b/etc/evergreen_yml_components/definitions.yml index a4242c8ef8c..7d6b4999d30 100644 --- a/etc/evergreen_yml_components/definitions.yml +++ b/etc/evergreen_yml_components/definitions.yml @@ -3503,6 +3503,18 @@ tasks: resmoke_jobs_max: 1 - func: "send benchmark results" +- <<: *benchmark_template + name: benchmarks_abt + tags: ["benchmarks"] + commands: + - func: "do benchmark setup" + - func: "run tests" + vars: + suites: benchmarks_abt + exec_timeout_secs: 18000 # 5 hour timeout. + resmoke_jobs_max: 1 + - func: "send benchmark results" + - <<: *run_jepsen_template name: jepsen_register_findAndModify tags: ["jepsen"] diff --git a/src/mongo/db/pipeline/SConscript b/src/mongo/db/pipeline/SConscript index 2347bd26c10..b8b17ac1ab9 100644 --- a/src/mongo/db/pipeline/SConscript +++ b/src/mongo/db/pipeline/SConscript @@ -503,6 +503,22 @@ env.Library( LIBDEPS_PRIVATE=[], ) +env.Benchmark( + target='abt_translation_bm', + source=[ + 'abt/abt_translate_bm_fixture.cpp', + 'abt/abt_translate_cq_bm.cpp', + 'abt/abt_translate_pipeline_bm.cpp', + ], + LIBDEPS=[ + '$BUILD_DIR/mongo/db/pipeline/pipeline', + '$BUILD_DIR/mongo/db/query/canonical_query', + '$BUILD_DIR/mongo/db/query/query_test_service_context', + '$BUILD_DIR/mongo/unittest/unittest', + '$BUILD_DIR/mongo/util/processinfo', + ], +) + env.CppUnitTest( target='db_pipeline_test', source=[ diff --git a/src/mongo/db/pipeline/abt/abt_translate_bm_fixture.cpp b/src/mongo/db/pipeline/abt/abt_translate_bm_fixture.cpp new file mode 100644 index 00000000000..6b00208dbbd --- /dev/null +++ b/src/mongo/db/pipeline/abt/abt_translate_bm_fixture.cpp @@ -0,0 +1,211 @@ +/** + * Copyright (C) 2022-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/db/pipeline/abt/abt_translate_bm_fixture.h" + +#include "mongo/bson/bsonobjbuilder.h" +#include "mongo/db/json.h" + +namespace mongo { +namespace { +BSONArray buildArray(int size) { + BSONArrayBuilder builder; + for (int i = 0; i < size; i++) { + builder.append(i); + } + return builder.arr(); +} + +std::string getField(int index) { + static constexpr StringData kViableChars = "abcdefghijklmnopqrstuvwxyz"_sd; + invariant(size_t(index) < kViableChars.size()); + return std::string(1, kViableChars[index]); +} + +BSONObj buildSimpleBSONSpec(int nFields, bool isMatch, bool isExclusion = false) { + BSONObjBuilder spec; + for (auto i = 0; i < nFields; i++) { + int val = isMatch ? i : (isExclusion ? 0 : 1); + spec.append(getField(i), val); + } + return spec.obj(); +} + +/** + * Builds a filter BSON with 'nFields' simple equality predicates. + */ +BSONObj buildSimpleMatchSpec(int nFields) { + return buildSimpleBSONSpec(nFields, true /*isMatch*/); +} + +/** + * Builds a projection BSON with 'nFields' simple inclusions or exclusions, depending on the + * 'isExclusion' parameter. + */ +BSONObj buildSimpleProjectSpec(int nFields, bool isExclusion) { + return buildSimpleBSONSpec(nFields, false /*isMatch*/, isExclusion); +} + +BSONObj buildNestedBSONSpec(int depth, bool isExclusion, int offset) { + std::string field; + for (auto i = 0; i < depth - 1; i++) { + field += getField(offset + i) += "."; + } + field += getField(offset + depth); + + return BSON(field << (isExclusion ? 0 : 1)); +} + +/** + * Builds a BSON representing a predicate on one dotted path, where the field has depth 'depth'. + */ +BSONObj buildNestedMatchSpec(int depth, int offset = 0) { + return buildNestedBSONSpec(depth, false /*isExclusion*/, offset); +} + +/** + * Builds a BSON representing a projection on one dotted path, where the field has depth 'depth'. + */ +BSONObj buildNestedProjectSpec(int depth, bool isExclusion, int offset = 0) { + return buildNestedBSONSpec(depth, isExclusion, offset); +} +} // namespace + +void ABTTranslateBenchmarkFixture::benchmarkMatch(benchmark::State& state) { + auto match = buildSimpleMatchSpec(1); + benchmarkABTTranslate(state, match, BSONObj()); +} +void ABTTranslateBenchmarkFixture::benchmarkMatchTwoFields(benchmark::State& state) { + auto match = buildSimpleMatchSpec(2); + benchmarkABTTranslate(state, match, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkMatchTwentyFields(benchmark::State& state) { + auto match = buildSimpleMatchSpec(20); + benchmarkABTTranslate(state, match, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkMatchDepthTwo(benchmark::State& state) { + auto match = buildNestedMatchSpec(2); + benchmarkABTTranslate(state, match, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkMatchDepthTwenty(benchmark::State& state) { + auto match = buildNestedMatchSpec(20); + benchmarkABTTranslate(state, match, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkMatchGtLt(benchmark::State& state) { + auto match = fromjson("{a: {$gt: -12, $lt: 5}}"); + benchmarkABTTranslate(state, match, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkMatchIn(benchmark::State& state) { + auto match = BSON("a" << BSON("$in" << buildArray(10))); + benchmarkABTTranslate(state, match, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkMatchInLarge(benchmark::State& state) { + auto match = BSON("a" << BSON("$in" << buildArray(1000))); + benchmarkABTTranslate(state, match, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkMatchElemMatch(benchmark::State& state) { + auto match = fromjson("{a: {$elemMatch: {b: {$eq: 2}, c: {$lt: 3}}}}"); + benchmarkABTTranslate(state, match, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkMatchComplex(benchmark::State& state) { + auto match = fromjson( + "{$and: [" + "{'a.b': {$not: {$eq: 2}}}," + "{'b.c': {$lte: {$eq: 'str'}}}," + "{$or: [{'c.d' : {$eq: 3}}, {'d.e': {$eq: 4}}]}," + "{$or: [" + "{'e.f': {$gt: 4}}," + "{$and: [" + "{'f.g': {$not: {$eq: 1}}}," + "{'g.h': {$eq: 3}}" + "]}" + "]}" + "]}}"); + benchmarkABTTranslate(state, match, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkProjectExclude(benchmark::State& state) { + auto project = buildSimpleProjectSpec(1, true /*isExclusion*/); + benchmarkABTTranslate(state, project, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkProjectInclude(benchmark::State& state) { + auto project = buildSimpleProjectSpec(1, false /*isExclusion*/); + benchmarkABTTranslate(state, project, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkProjectIncludeTwoFields(benchmark::State& state) { + auto project = buildSimpleProjectSpec(2, false /*isExclusion*/); + benchmarkABTTranslate(state, project, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkProjectIncludeTwentyFields(benchmark::State& state) { + auto project = buildSimpleProjectSpec(20, false /*isExclusion*/); + benchmarkABTTranslate(state, project, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkProjectIncludeDepthTwo(benchmark::State& state) { + auto project = buildNestedProjectSpec(2, false /*isExclusion*/); + benchmarkABTTranslate(state, project, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkProjectIncludeDepthTwenty(benchmark::State& state) { + auto project = buildNestedProjectSpec(20, false /*isExclusion*/); + benchmarkABTTranslate(state, project, BSONObj()); +} + +void ABTTranslateBenchmarkFixture::benchmarkTwoStages(benchmark::State& state) { + // Builds a match on a nested field and then excludes that nested field. + std::vector<BSONObj> pipeline; + pipeline.push_back(BSON("$match" << buildNestedMatchSpec(3))); + pipeline.push_back(BSON("$project" << buildNestedProjectSpec(3, true /*isExclusion*/))); + benchmarkABTTranslate(state, pipeline); +} + +void ABTTranslateBenchmarkFixture::benchmarkTwentyStages(benchmark::State& state) { + // Builds a sequence of alternating $match and $project stages which match on a nested field and + // then exclude that field. + std::vector<BSONObj> pipeline; + for (int i = 0; i < 10; i++) { + pipeline.push_back(BSON("$match" << buildNestedMatchSpec(3, i))); + pipeline.push_back(BSON("$project" << buildNestedProjectSpec(3, true /*exclusion*/, i))); + } + benchmarkABTTranslate(state, pipeline); +} + + +} // namespace mongo diff --git a/src/mongo/db/pipeline/abt/abt_translate_bm_fixture.h b/src/mongo/db/pipeline/abt/abt_translate_bm_fixture.h new file mode 100644 index 00000000000..0ab40ed52fe --- /dev/null +++ b/src/mongo/db/pipeline/abt/abt_translate_bm_fixture.h @@ -0,0 +1,137 @@ +/** + * Copyright (C) 2022-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/platform/basic.h" + +#include <benchmark/benchmark.h> + +#include "mongo/bson/bsonobj.h" + +namespace mongo { + +class ABTTranslateBenchmarkFixture : public benchmark::Fixture { +public: + virtual void benchmarkABTTranslate(benchmark::State& state, + BSONObj matchSpec, + BSONObj projectSpec) = 0; + virtual void benchmarkABTTranslate(benchmark::State& state, + const std::vector<BSONObj>& pipeline) = 0; + + void benchmarkMatch(benchmark::State& state); + void benchmarkMatchTwoFields(benchmark::State& state); + void benchmarkMatchTwentyFields(benchmark::State& state); + + void benchmarkMatchDepthTwo(benchmark::State& state); + void benchmarkMatchDepthTwenty(benchmark::State& state); + + void benchmarkMatchGtLt(benchmark::State& state); + void benchmarkMatchIn(benchmark::State& state); + void benchmarkMatchInLarge(benchmark::State& state); + void benchmarkMatchElemMatch(benchmark::State& state); + void benchmarkMatchComplex(benchmark::State& state); + + void benchmarkProjectExclude(benchmark::State& state); + void benchmarkProjectInclude(benchmark::State& state); + void benchmarkProjectIncludeTwoFields(benchmark::State& state); + void benchmarkProjectIncludeTwentyFields(benchmark::State& state); + + void benchmarkProjectIncludeDepthTwo(benchmark::State& state); + void benchmarkProjectIncludeDepthTwenty(benchmark::State& state); + + void benchmarkTwoStages(benchmark::State& state); + void benchmarkTwentyStages(benchmark::State& state); +}; + +// These benchmarks cover some simple queries which are currently CQF-eligible. As more support +// is added to CQF, more benchmarks may be added here as needed. +#define BENCHMARK_MQL_TRANSLATION(Fixture) \ + \ + BENCHMARK_F(Fixture, Match)(benchmark::State & state) { \ + benchmarkMatch(state); \ + } \ + BENCHMARK_F(Fixture, MatchTwoFields)(benchmark::State & state) { \ + benchmarkMatchTwoFields(state); \ + } \ + BENCHMARK_F(Fixture, MatchTwentyFields)(benchmark::State & state) { \ + benchmarkMatchTwentyFields(state); \ + } \ + BENCHMARK_F(Fixture, MatchDepthTwo)(benchmark::State & state) { \ + benchmarkMatchDepthTwo(state); \ + } \ + BENCHMARK_F(Fixture, MatchDepthTwenty)(benchmark::State & state) { \ + benchmarkMatchDepthTwenty(state); \ + } \ + BENCHMARK_F(Fixture, MatchGtLt)(benchmark::State & state) { \ + benchmarkMatchGtLt(state); \ + } \ + BENCHMARK_F(Fixture, MatchIn)(benchmark::State & state) { \ + benchmarkMatchIn(state); \ + } \ + BENCHMARK_F(Fixture, MatchInLarge)(benchmark::State & state) { \ + benchmarkMatchInLarge(state); \ + } \ + BENCHMARK_F(Fixture, MatchElemMatch)(benchmark::State & state) { \ + benchmarkMatchElemMatch(state); \ + } \ + BENCHMARK_F(Fixture, MatchComplex)(benchmark::State & state) { \ + benchmarkMatchComplex(state); \ + } \ + BENCHMARK_F(Fixture, ProjectExclude)(benchmark::State & state) { \ + benchmarkProjectExclude(state); \ + } \ + BENCHMARK_F(Fixture, ProjectInclude)(benchmark::State & state) { \ + benchmarkProjectInclude(state); \ + } \ + BENCHMARK_F(Fixture, ProjectIncludeTwoFields)(benchmark::State & state) { \ + benchmarkProjectIncludeTwoFields(state); \ + } \ + BENCHMARK_F(Fixture, ProjectIncludeTwentyFields)(benchmark::State & state) { \ + benchmarkProjectIncludeTwentyFields(state); \ + } \ + BENCHMARK_F(Fixture, ProjectIncludeDepthTwo)(benchmark::State & state) { \ + benchmarkProjectIncludeDepthTwo(state); \ + } \ + BENCHMARK_F(Fixture, ProjectIncludeDepthTwenty)(benchmark::State & state) { \ + benchmarkProjectIncludeDepthTwenty(state); \ + } + +// Queries which are expressed as pipelines should be added here because they cannot go through +// find translation. +#define BENCHMARK_MQL_PIPELINE_TRANSLATION(Fixture) \ + \ + BENCHMARK_F(Fixture, TwoStages)(benchmark::State & state) { \ + benchmarkTwoStages(state); \ + } \ + BENCHMARK_F(Fixture, TwentyStages)(benchmark::State & state) { \ + benchmarkTwentyStages(state); \ + } + +} // namespace mongo diff --git a/src/mongo/db/pipeline/abt/abt_translate_cq_bm.cpp b/src/mongo/db/pipeline/abt/abt_translate_cq_bm.cpp new file mode 100644 index 00000000000..8603ea2d7c0 --- /dev/null +++ b/src/mongo/db/pipeline/abt/abt_translate_cq_bm.cpp @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2022-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include <benchmark/benchmark.h> + +#include "mongo/bson/bsonobjbuilder.h" +#include "mongo/db/pipeline/abt/abt_translate_bm_fixture.h" +#include "mongo/db/pipeline/abt/canonical_query_translation.h" +#include "mongo/db/query/canonical_query.h" +#include "mongo/db/query/query_test_service_context.h" + +namespace mongo::optimizer { +namespace { +/** + * Benchmarks translation from CanonicalQuery to ABT. + */ +class CanonicalQueryABTTranslate : public ABTTranslateBenchmarkFixture { +public: + CanonicalQueryABTTranslate() {} + + void benchmarkABTTranslate(benchmark::State& state, + const std::vector<BSONObj>& pipeline) override final { + state.SkipWithError("Find translation fixture cannot translate a pieline"); + return; + } + + void benchmarkABTTranslate(benchmark::State& state, + BSONObj matchSpec, + BSONObj projectSpec) override final { + QueryTestServiceContext testServiceContext; + auto opCtx = testServiceContext.makeOperationContext(); + auto nss = NamespaceString("test.bm"); + + Metadata metadata{{}}; + PrefixId prefixId; + std::string scanProjName = prefixId.getNextId("scan"); + + auto findCommand = std::make_unique<FindCommandRequest>(nss); + findCommand->setFilter(matchSpec); + findCommand->setProjection(projectSpec); + auto cq = CanonicalQuery::canonicalize(opCtx.get(), std::move(findCommand)); + if (!cq.isOK()) { + state.SkipWithError("Canonical query could not be created"); + return; + } + + // This is where recording starts. + for (auto keepRunning : state) { + benchmark::DoNotOptimize( + translateCanonicalQueryToABT(metadata, + *cq.getValue(), + scanProjName, + make<ScanNode>(scanProjName, "collection"), + prefixId)); + benchmark::ClobberMemory(); + } + } +}; + +BENCHMARK_MQL_TRANSLATION(CanonicalQueryABTTranslate) +} // namespace +} // namespace mongo::optimizer diff --git a/src/mongo/db/pipeline/abt/abt_translate_pipeline_bm.cpp b/src/mongo/db/pipeline/abt/abt_translate_pipeline_bm.cpp new file mode 100644 index 00000000000..f878c494c13 --- /dev/null +++ b/src/mongo/db/pipeline/abt/abt_translate_pipeline_bm.cpp @@ -0,0 +1,90 @@ +/** + * Copyright (C) 2022-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include <benchmark/benchmark.h> + +#include "mongo/bson/bsonobjbuilder.h" +#include "mongo/db/pipeline/abt/abt_translate_bm_fixture.h" +#include "mongo/db/pipeline/abt/document_source_visitor.h" +#include "mongo/db/pipeline/expression_context_for_test.h" +#include "mongo/db/query/query_test_service_context.h" + +namespace mongo::optimizer { +namespace { +/** + * Benchmarks translation from optimized Pipeline to ABT. + */ +class PipelineABTTranslateBenchmark : public ABTTranslateBenchmarkFixture { +public: + PipelineABTTranslateBenchmark() {} + + void benchmarkABTTranslate(benchmark::State& state, + BSONObj matchSpec, + BSONObj projectSpec) override final { + std::vector<BSONObj> pipeline; + if (!matchSpec.isEmpty()) { + pipeline.push_back(BSON("$match" << matchSpec)); + } + if (!projectSpec.isEmpty()) { + pipeline.push_back(BSON("$project" << projectSpec)); + } + benchmarkABTTranslate(state, pipeline); + } + + void benchmarkABTTranslate(benchmark::State& state, + const std::vector<BSONObj>& pipeline) override final { + QueryTestServiceContext testServiceContext; + auto opCtx = testServiceContext.makeOperationContext(); + auto expCtx = new ExpressionContextForTest(opCtx.get(), NamespaceString("test.bm")); + + Metadata metadata{{}}; + PrefixId prefixId; + std::string scanProjName = prefixId.getNextId("scan"); + + std::unique_ptr<Pipeline, PipelineDeleter> parsedPipeline = + Pipeline::parse(pipeline, expCtx); + parsedPipeline->optimizePipeline(); + + // This is where recording starts. + for (auto keepRunning : state) { + benchmark::DoNotOptimize( + translatePipelineToABT(metadata, + *parsedPipeline, + scanProjName, + make<ScanNode>(scanProjName, "collection"), + prefixId)); + benchmark::ClobberMemory(); + } + } +}; + +BENCHMARK_MQL_TRANSLATION(PipelineABTTranslateBenchmark) +BENCHMARK_MQL_PIPELINE_TRANSLATION(PipelineABTTranslateBenchmark) +} // namespace +} // namespace mongo::optimizer |