summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHana Pearlman <hana.pearlman@mongodb.com>2022-11-02 18:18:44 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-11-02 19:05:58 +0000
commitea4fa8178b52d17a61d5104543890a5f5079f5f6 (patch)
tree412a6ff343a203b255848b90b563e15c75286a21
parentd2fb5646942d989da1819e49ec2ab924927fa270 (diff)
downloadmongo-ea4fa8178b52d17a61d5104543890a5f5079f5f6.tar.gz
SERVER-62033: Add C++ performance benchmarks for ABT translation
-rw-r--r--buildscripts/resmokeconfig/suites/benchmarks.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/benchmarks_abt.yml14
-rw-r--r--etc/evergreen_yml_components/definitions.yml12
-rw-r--r--src/mongo/db/pipeline/SConscript16
-rw-r--r--src/mongo/db/pipeline/abt/abt_translate_bm_fixture.cpp211
-rw-r--r--src/mongo/db/pipeline/abt/abt_translate_bm_fixture.h137
-rw-r--r--src/mongo/db/pipeline/abt/abt_translate_cq_bm.cpp88
-rw-r--r--src/mongo/db/pipeline/abt/abt_translate_pipeline_bm.cpp90
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