Skip to content

Commit 32a793d

Browse files
jnthntatumcopybara-github
authored andcommitted
Add benchmarks for enum resolution for the expression builder.
PiperOrigin-RevId: 740854454
1 parent 06ad429 commit 32a793d

File tree

2 files changed

+177
-8
lines changed

2 files changed

+177
-8
lines changed

eval/tests/BUILD

+4-2
Original file line numberDiff line numberDiff line change
@@ -185,16 +185,18 @@ cc_test(
185185
tags = ["benchmark"],
186186
deps = [
187187
":request_context_cc_proto",
188+
"//common:minimal_descriptor_pool",
188189
"//eval/public:builtin_func_registrar",
189190
"//eval/public:cel_expr_builder_factory",
190191
"//eval/public:cel_expression",
191192
"//eval/public:cel_options",
193+
"//eval/public:cel_type_registry",
192194
"//internal:benchmark",
193195
"//internal:status_macros",
194196
"//internal:testing",
195197
"//parser",
196-
"@com_google_absl//absl/container:flat_hash_set",
197-
"@com_google_absl//absl/container:node_hash_set",
198+
"@com_google_absl//absl/log:absl_check",
199+
"@com_google_absl//absl/status:statusor",
198200
"@com_google_absl//absl/strings",
199201
"@com_google_cel_spec//proto/cel/expr:checked_cc_proto",
200202
"@com_google_cel_spec//proto/cel/expr:syntax_cc_proto",

eval/tests/expression_builder_benchmark_test.cc

+173-6
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,37 @@
1515
*/
1616

1717
#include <cmath>
18+
#include <memory>
1819
#include <string>
20+
#include <utility>
21+
#include <vector>
1922

2023
#include "cel/expr/checked.pb.h"
2124
#include "cel/expr/syntax.pb.h"
22-
#include "google/protobuf/text_format.h"
23-
#include "absl/container/flat_hash_set.h"
24-
#include "absl/container/node_hash_set.h"
25+
#include "absl/log/absl_check.h"
26+
#include "absl/status/statusor.h"
2527
#include "absl/strings/str_cat.h"
28+
#include "absl/strings/string_view.h"
29+
#include "common/minimal_descriptor_pool.h"
2630
#include "eval/public/builtin_func_registrar.h"
2731
#include "eval/public/cel_expr_builder_factory.h"
2832
#include "eval/public/cel_expression.h"
2933
#include "eval/public/cel_options.h"
34+
#include "eval/public/cel_type_registry.h"
3035
#include "eval/tests/request_context.pb.h"
3136
#include "internal/benchmark.h"
3237
#include "internal/status_macros.h"
3338
#include "internal/testing.h"
3439
#include "parser/parser.h"
40+
#include "google/protobuf/arena.h"
3541

3642
namespace google::api::expr::runtime {
3743

3844
namespace {
3945

4046
using cel::expr::CheckedExpr;
4147
using cel::expr::ParsedExpr;
48+
using google::api::expr::parser::Parse;
4249

4350
enum BenchmarkParam : int {
4451
kDefault = 0,
@@ -100,6 +107,106 @@ BENCHMARK(BM_SymbolicPolicy)
100107
->Arg(BenchmarkParam::kDefault)
101108
->Arg(BenchmarkParam::kFoldConstants);
102109

110+
absl::StatusOr<std::unique_ptr<CelExpressionBuilder>> MakeBuilderForEnums(
111+
absl::string_view container, absl::string_view enum_type,
112+
int num_enum_values) {
113+
auto builder =
114+
CreateCelExpressionBuilder(cel::GetMinimalDescriptorPool(), nullptr, {});
115+
builder->set_container(std::string(container));
116+
CelTypeRegistry* type_registry = builder->GetTypeRegistry();
117+
std::vector<CelTypeRegistry::Enumerator> enumerators;
118+
enumerators.reserve(num_enum_values);
119+
for (int i = 0; i < num_enum_values; ++i) {
120+
enumerators.push_back(
121+
CelTypeRegistry::Enumerator{absl::StrCat("ENUM_VALUE_", i), i});
122+
}
123+
type_registry->RegisterEnum(enum_type, std::move(enumerators));
124+
125+
CEL_RETURN_IF_ERROR(RegisterBuiltinFunctions(builder->GetRegistry()));
126+
return builder;
127+
}
128+
129+
void BM_EnumResolutionSimple(benchmark::State& state) {
130+
static const CelExpressionBuilder* builder = []() {
131+
auto builder = MakeBuilderForEnums("", "com.example.TestEnum", 4);
132+
ABSL_CHECK_OK(builder.status());
133+
return builder->release();
134+
}();
135+
136+
ASSERT_OK_AND_ASSIGN(auto expr, Parse("com.example.TestEnum.ENUM_VALUE_0"));
137+
138+
for (auto _ : state) {
139+
ASSERT_OK_AND_ASSIGN(
140+
auto expression,
141+
builder->CreateExpression(&expr.expr(), &expr.source_info()));
142+
benchmark::DoNotOptimize(expression);
143+
}
144+
}
145+
146+
BENCHMARK(BM_EnumResolutionSimple)->ThreadRange(1, 32);
147+
148+
void BM_EnumResolutionContainer(benchmark::State& state) {
149+
static const CelExpressionBuilder* builder = []() {
150+
auto builder =
151+
MakeBuilderForEnums("com.example", "com.example.TestEnum", 4);
152+
ABSL_CHECK_OK(builder.status());
153+
return builder->release();
154+
}();
155+
156+
ASSERT_OK_AND_ASSIGN(auto expr, Parse("TestEnum.ENUM_VALUE_0"));
157+
158+
for (auto _ : state) {
159+
ASSERT_OK_AND_ASSIGN(
160+
auto expression,
161+
builder->CreateExpression(&expr.expr(), &expr.source_info()));
162+
benchmark::DoNotOptimize(expression);
163+
}
164+
}
165+
166+
BENCHMARK(BM_EnumResolutionContainer)->ThreadRange(1, 32);
167+
168+
void BM_EnumResolution32Candidate(benchmark::State& state) {
169+
static const CelExpressionBuilder* builder = []() {
170+
auto builder =
171+
MakeBuilderForEnums("com.example.foo", "com.example.foo.TestEnum", 8);
172+
ABSL_CHECK_OK(builder.status());
173+
return builder->release();
174+
}();
175+
176+
ASSERT_OK_AND_ASSIGN(auto expr,
177+
Parse("com.example.foo.TestEnum.ENUM_VALUE_0"));
178+
179+
for (auto _ : state) {
180+
ASSERT_OK_AND_ASSIGN(
181+
auto expression,
182+
builder->CreateExpression(&expr.expr(), &expr.source_info()));
183+
benchmark::DoNotOptimize(expression);
184+
}
185+
}
186+
187+
BENCHMARK(BM_EnumResolution32Candidate)->ThreadRange(1, 32);
188+
189+
void BM_EnumResolution256Candidate(benchmark::State& state) {
190+
static const CelExpressionBuilder* builder = []() {
191+
auto builder =
192+
MakeBuilderForEnums("com.example.foo", "com.example.foo.TestEnum", 64);
193+
ABSL_CHECK_OK(builder.status());
194+
return builder->release();
195+
}();
196+
197+
ASSERT_OK_AND_ASSIGN(auto expr,
198+
Parse("com.example.foo.TestEnum.ENUM_VALUE_0"));
199+
200+
for (auto _ : state) {
201+
ASSERT_OK_AND_ASSIGN(
202+
auto expression,
203+
builder->CreateExpression(&expr.expr(), &expr.source_info()));
204+
benchmark::DoNotOptimize(expression);
205+
}
206+
}
207+
208+
BENCHMARK(BM_EnumResolution256Candidate)->ThreadRange(1, 32);
209+
103210
void BM_NestedComprehension(benchmark::State& state) {
104211
auto param = static_cast<BenchmarkParam>(state.range(0));
105212

@@ -155,6 +262,32 @@ BENCHMARK(BM_Comparisons)
155262
->Arg(BenchmarkParam::kDefault)
156263
->Arg(BenchmarkParam::kFoldConstants);
157264

265+
void BM_ComparisonsConcurrent(benchmark::State& state) {
266+
ASSERT_OK_AND_ASSIGN(ParsedExpr expr, parser::Parse(R"(
267+
v11 < v12 && v12 < v13
268+
&& v21 > v22 && v22 > v23
269+
&& v31 == v32 && v32 == v33
270+
&& v11 != v12 && v12 != v13
271+
)"));
272+
273+
static const CelExpressionBuilder* builder = [] {
274+
InterpreterOptions options;
275+
auto builder = CreateCelExpressionBuilder(options);
276+
auto reg_status = RegisterBuiltinFunctions(builder->GetRegistry());
277+
ABSL_CHECK_OK(reg_status);
278+
return builder.release();
279+
}();
280+
281+
for (auto _ : state) {
282+
ASSERT_OK_AND_ASSIGN(
283+
auto expression,
284+
builder->CreateExpression(&expr.expr(), &expr.source_info()));
285+
benchmark::DoNotOptimize(expression);
286+
}
287+
}
288+
289+
BENCHMARK(BM_ComparisonsConcurrent)->ThreadRange(1, 32);
290+
158291
void RegexPrecompilationBench(bool enabled, benchmark::State& state) {
159292
auto param = static_cast<BenchmarkParam>(state.range(0));
160293

@@ -207,9 +340,11 @@ void BM_StringConcat(benchmark::State& state) {
207340
auto size = state.range(1);
208341

209342
std::string source = "'1234567890' + '1234567890'";
210-
auto iter = static_cast<int>(std::log2(size));
211-
for (int i = 1; i < iter; i++) {
212-
source = absl::StrCat(source, " + ", source);
343+
auto height = static_cast<int>(std::log2(size));
344+
for (int i = 1; i < height; i++) {
345+
// Force the parse to be a binary tree, otherwise we can hit
346+
// recursion limits.
347+
source = absl::StrCat("(", source, " + ", source, ")");
213348
}
214349

215350
// add a non const branch to the expression.
@@ -244,5 +379,37 @@ BENCHMARK(BM_StringConcat)
244379
->Args({BenchmarkParam::kFoldConstants, 16})
245380
->Args({BenchmarkParam::kFoldConstants, 32});
246381

382+
void BM_StringConcat32Concurrent(benchmark::State& state) {
383+
std::string source = "'1234567890' + '1234567890'";
384+
auto height = static_cast<int>(std::log2(32));
385+
for (int i = 1; i < height; i++) {
386+
// Force the parse to be a binary tree, otherwise we can hit
387+
// recursion limits.
388+
source = absl::StrCat("(", source, " + ", source, ")");
389+
}
390+
391+
// add a non const branch to the expression.
392+
absl::StrAppend(&source, " + identifier");
393+
394+
ASSERT_OK_AND_ASSIGN(ParsedExpr expr, parser::Parse(source));
395+
396+
static const CelExpressionBuilder* builder = [] {
397+
InterpreterOptions options;
398+
auto builder = CreateCelExpressionBuilder(options);
399+
auto reg_status = RegisterBuiltinFunctions(builder->GetRegistry());
400+
ABSL_CHECK_OK(reg_status);
401+
return builder.release();
402+
}();
403+
404+
for (auto _ : state) {
405+
ASSERT_OK_AND_ASSIGN(
406+
auto expression,
407+
builder->CreateExpression(&expr.expr(), &expr.source_info()));
408+
benchmark::DoNotOptimize(expression);
409+
}
410+
}
411+
412+
BENCHMARK(BM_StringConcat32Concurrent)->ThreadRange(1, 32);
413+
247414
} // namespace
248415
} // namespace google::api::expr::runtime

0 commit comments

Comments
 (0)