Skip to content

Commit 579d285

Browse files
CEL Dev Teamcopybara-github
authored andcommitted
Add benchmark test for field access implementation.
Adds a `cc_test` target for benchmarking `field_access_impl.cc`. PiperOrigin-RevId: 922419518
1 parent 9fb8e10 commit 579d285

2 files changed

Lines changed: 259 additions & 0 deletions

File tree

eval/public/structs/BUILD

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,3 +442,23 @@ cc_test(
442442
"@com_google_protobuf//:protobuf",
443443
],
444444
)
445+
446+
cc_test(
447+
name = "field_access_impl_benchmark_test",
448+
srcs = ["field_access_impl_benchmark_test.cc"],
449+
tags = [
450+
"benchmark",
451+
"manual",
452+
],
453+
deps = [
454+
":cel_proto_wrapper",
455+
":field_access_impl",
456+
"//eval/public:cel_options",
457+
"//eval/public:cel_value",
458+
"//extensions/protobuf/internal:map_reflection",
459+
"//internal:benchmark",
460+
"//internal:testing",
461+
"@com_google_cel_spec//proto/cel/expr/conformance/proto3:test_all_types_cc_proto",
462+
"@com_google_protobuf//:protobuf",
463+
],
464+
)
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "eval/public/cel_options.h"
16+
#include "eval/public/cel_value.h"
17+
#include "eval/public/structs/cel_proto_wrapper.h"
18+
#include "eval/public/structs/field_access_impl.h"
19+
#include "extensions/protobuf/internal/map_reflection.h"
20+
#include "internal/benchmark.h"
21+
#include "cel/expr/conformance/proto3/test_all_types.pb.h"
22+
#include "google/protobuf/arena.h"
23+
#include "google/protobuf/descriptor.h"
24+
#include "google/protobuf/map_field.h"
25+
#include "google/protobuf/message.h"
26+
27+
namespace google::api::expr::runtime::internal {
28+
namespace {
29+
30+
using ::cel::expr::conformance::proto3::TestAllTypes;
31+
32+
void BM_CreateValueFromSingleField_Int64(benchmark::State& state) {
33+
google::protobuf::Arena arena;
34+
TestAllTypes msg;
35+
msg.set_single_int64(42);
36+
const google::protobuf::FieldDescriptor* desc =
37+
TestAllTypes::descriptor()->FindFieldByName("single_int64");
38+
39+
for (auto _ : state) {
40+
auto value = CreateValueFromSingleField(
41+
&msg, desc, ProtoWrapperTypeOptions::kUnsetProtoDefault,
42+
&CelProtoWrapper::InternalWrapMessage, &arena);
43+
benchmark::DoNotOptimize(value);
44+
}
45+
}
46+
BENCHMARK(BM_CreateValueFromSingleField_Int64);
47+
48+
void BM_CreateValueFromSingleField_String(benchmark::State& state) {
49+
google::protobuf::Arena arena;
50+
TestAllTypes msg;
51+
msg.set_single_string("hello world");
52+
const google::protobuf::FieldDescriptor* desc =
53+
TestAllTypes::descriptor()->FindFieldByName("single_string");
54+
55+
for (auto _ : state) {
56+
auto value = CreateValueFromSingleField(
57+
&msg, desc, ProtoWrapperTypeOptions::kUnsetProtoDefault,
58+
&CelProtoWrapper::InternalWrapMessage, &arena);
59+
benchmark::DoNotOptimize(value);
60+
}
61+
}
62+
BENCHMARK(BM_CreateValueFromSingleField_String);
63+
64+
void BM_CreateValueFromSingleField_Message(benchmark::State& state) {
65+
google::protobuf::Arena arena;
66+
TestAllTypes msg;
67+
msg.mutable_standalone_message()->set_bb(123);
68+
const google::protobuf::FieldDescriptor* desc =
69+
TestAllTypes::descriptor()->FindFieldByName("standalone_message");
70+
71+
for (auto _ : state) {
72+
auto value = CreateValueFromSingleField(
73+
&msg, desc, ProtoWrapperTypeOptions::kUnsetProtoDefault,
74+
&CelProtoWrapper::InternalWrapMessage, &arena);
75+
benchmark::DoNotOptimize(value);
76+
}
77+
}
78+
BENCHMARK(BM_CreateValueFromSingleField_Message);
79+
80+
void BM_CreateValueFromRepeatedField_Int64(benchmark::State& state) {
81+
google::protobuf::Arena arena;
82+
TestAllTypes msg;
83+
msg.add_repeated_int64(42);
84+
const google::protobuf::FieldDescriptor* desc =
85+
TestAllTypes::descriptor()->FindFieldByName("repeated_int64");
86+
87+
for (auto _ : state) {
88+
auto value = CreateValueFromRepeatedField(
89+
&msg, desc, 0, &CelProtoWrapper::InternalWrapMessage, &arena);
90+
benchmark::DoNotOptimize(value);
91+
}
92+
}
93+
BENCHMARK(BM_CreateValueFromRepeatedField_Int64);
94+
95+
void BM_CreateValueFromRepeatedField_String(benchmark::State& state) {
96+
google::protobuf::Arena arena;
97+
TestAllTypes msg;
98+
msg.add_repeated_string("hello world");
99+
const google::protobuf::FieldDescriptor* desc =
100+
TestAllTypes::descriptor()->FindFieldByName("repeated_string");
101+
102+
for (auto _ : state) {
103+
auto value = CreateValueFromRepeatedField(
104+
&msg, desc, 0, &CelProtoWrapper::InternalWrapMessage, &arena);
105+
benchmark::DoNotOptimize(value);
106+
}
107+
}
108+
BENCHMARK(BM_CreateValueFromRepeatedField_String);
109+
110+
void BM_CreateValueFromMapValue_Int64(benchmark::State& state) {
111+
google::protobuf::Arena arena;
112+
TestAllTypes msg;
113+
(*msg.mutable_map_int64_int64())[42] = 100;
114+
const google::protobuf::FieldDescriptor* map_desc =
115+
TestAllTypes::descriptor()->FindFieldByName("map_int64_int64");
116+
const google::protobuf::FieldDescriptor* value_desc =
117+
map_desc->message_type()->FindFieldByName("value");
118+
119+
google::protobuf::ConstMapIterator iter =
120+
cel::extensions::protobuf_internal::ConstMapBegin(*msg.GetReflection(),
121+
msg, *map_desc);
122+
google::protobuf::MapValueConstRef value_ref = iter.GetValueRef();
123+
124+
for (auto _ : state) {
125+
auto value =
126+
CreateValueFromMapValue(&msg, value_desc, &value_ref,
127+
&CelProtoWrapper::InternalWrapMessage, &arena);
128+
benchmark::DoNotOptimize(value);
129+
}
130+
}
131+
BENCHMARK(BM_CreateValueFromMapValue_Int64);
132+
133+
void BM_SetValueToSingleField_Int64(benchmark::State& state) {
134+
google::protobuf::Arena arena;
135+
TestAllTypes msg;
136+
const google::protobuf::FieldDescriptor* desc =
137+
TestAllTypes::descriptor()->FindFieldByName("single_int64");
138+
CelValue val = CelValue::CreateInt64(42);
139+
140+
for (auto _ : state) {
141+
auto status = SetValueToSingleField(val, desc, &msg, &arena);
142+
benchmark::DoNotOptimize(status);
143+
}
144+
}
145+
BENCHMARK(BM_SetValueToSingleField_Int64);
146+
147+
void BM_SetValueToSingleField_String(benchmark::State& state) {
148+
google::protobuf::Arena arena;
149+
TestAllTypes msg;
150+
const google::protobuf::FieldDescriptor* desc =
151+
TestAllTypes::descriptor()->FindFieldByName("single_string");
152+
CelValue val = CelValue::CreateStringView("hello world");
153+
154+
for (auto _ : state) {
155+
auto status = SetValueToSingleField(val, desc, &msg, &arena);
156+
benchmark::DoNotOptimize(status);
157+
}
158+
}
159+
BENCHMARK(BM_SetValueToSingleField_String);
160+
161+
void BM_SetValueToSingleField_Message(benchmark::State& state) {
162+
google::protobuf::Arena arena;
163+
TestAllTypes msg;
164+
const google::protobuf::FieldDescriptor* desc =
165+
TestAllTypes::descriptor()->FindFieldByName("standalone_message");
166+
167+
TestAllTypes::NestedMessage nested_msg;
168+
nested_msg.set_bb(123);
169+
CelValue val = CelProtoWrapper::CreateMessage(&nested_msg, &arena);
170+
171+
for (auto _ : state) {
172+
auto status = SetValueToSingleField(val, desc, &msg, &arena);
173+
benchmark::DoNotOptimize(status);
174+
}
175+
}
176+
BENCHMARK(BM_SetValueToSingleField_Message);
177+
178+
void BM_AddValueToRepeatedField_Int64(benchmark::State& state) {
179+
google::protobuf::Arena arena;
180+
TestAllTypes msg;
181+
const google::protobuf::FieldDescriptor* desc =
182+
TestAllTypes::descriptor()->FindFieldByName("repeated_int64");
183+
CelValue val = CelValue::CreateInt64(42);
184+
185+
for (auto _ : state) {
186+
msg.clear_repeated_int64();
187+
auto status = AddValueToRepeatedField(val, desc, &msg, &arena);
188+
benchmark::DoNotOptimize(status);
189+
}
190+
}
191+
BENCHMARK(BM_AddValueToRepeatedField_Int64);
192+
193+
void BM_AddValueToRepeatedField_String(benchmark::State& state) {
194+
google::protobuf::Arena arena;
195+
TestAllTypes msg;
196+
const google::protobuf::FieldDescriptor* desc =
197+
TestAllTypes::descriptor()->FindFieldByName("repeated_string");
198+
CelValue val = CelValue::CreateStringView("hello world");
199+
200+
for (auto _ : state) {
201+
msg.clear_repeated_string();
202+
auto status = AddValueToRepeatedField(val, desc, &msg, &arena);
203+
benchmark::DoNotOptimize(status);
204+
}
205+
}
206+
BENCHMARK(BM_AddValueToRepeatedField_String);
207+
208+
void BM_CreateValueFromRepeatedField_StringPiece(benchmark::State& state) {
209+
google::protobuf::Arena arena;
210+
TestAllTypes msg;
211+
msg.add_repeated_string_piece("hello world");
212+
const google::protobuf::FieldDescriptor* desc =
213+
TestAllTypes::descriptor()->FindFieldByName("repeated_string_piece");
214+
215+
for (auto _ : state) {
216+
auto value = CreateValueFromRepeatedField(
217+
&msg, desc, 0, &CelProtoWrapper::InternalWrapMessage, &arena);
218+
benchmark::DoNotOptimize(value);
219+
}
220+
}
221+
BENCHMARK(BM_CreateValueFromRepeatedField_StringPiece);
222+
223+
void BM_AddValueToRepeatedField_StringPiece(benchmark::State& state) {
224+
google::protobuf::Arena arena;
225+
TestAllTypes msg;
226+
const google::protobuf::FieldDescriptor* desc =
227+
TestAllTypes::descriptor()->FindFieldByName("repeated_string_piece");
228+
CelValue val = CelValue::CreateStringView("hello world");
229+
230+
for (auto _ : state) {
231+
msg.clear_repeated_string_piece();
232+
auto status = AddValueToRepeatedField(val, desc, &msg, &arena);
233+
benchmark::DoNotOptimize(status);
234+
}
235+
}
236+
BENCHMARK(BM_AddValueToRepeatedField_StringPiece);
237+
238+
} // namespace
239+
} // namespace google::api::expr::runtime::internal

0 commit comments

Comments
 (0)