4141#include " common/native_type.h"
4242#include " common/value.h"
4343#include " eval/tests/request_context.pb.h"
44+ #include " extensions/comprehensions_v2_functions.h"
45+ #include " extensions/comprehensions_v2_macros.h"
4446#include " extensions/protobuf/runtime_adapter.h"
4547#include " extensions/protobuf/value.h"
4648#include " internal/benchmark.h"
4749#include " internal/testing.h"
4850#include " internal/testing_descriptor_pool.h"
4951#include " internal/testing_message_factory.h"
52+ #include " parser/macro_registry.h"
5053#include " parser/parser.h"
5154#include " runtime/activation.h"
5255#include " runtime/constant_folding.h"
@@ -70,6 +73,7 @@ using ::cel::extensions::ProtobufRuntimeAdapter;
7073using ::cel::expr::Expr;
7174using ::cel::expr::ParsedExpr;
7275using ::cel::expr::SourceInfo;
76+ using ::google::api::expr::parser::EnrichedParse;
7377using ::google::api::expr::parser::Parse;
7478using ::google::api::expr::runtime::RequestContext;
7579using ::google::rpc::context::AttributeContext;
@@ -1270,6 +1274,62 @@ void BM_ComprehensionCpp(benchmark::State& state) {
12701274
12711275BENCHMARK (BM_ComprehensionCpp)->Range (1 , 1 << 20 );
12721276
1277+ void BM_MapTransformComprehension (benchmark::State& state) {
1278+ ASSERT_OK_AND_ASSIGN (auto source,
1279+ NewSource (" map_var.transformMapEntry(k, v, {v:k})" ));
1280+
1281+ MacroRegistry registry;
1282+ ASSERT_THAT (
1283+ extensions::RegisterComprehensionsV2Macros (registry, ParserOptions ()),
1284+ IsOk ());
1285+
1286+ ASSERT_OK_AND_ASSIGN (auto parsed_expr,
1287+ EnrichedParse (*source, registry, ParserOptions ()));
1288+
1289+ RuntimeOptions options = GetOptions ();
1290+ options.comprehension_max_iterations = 10000000 ;
1291+
1292+ // This is a critical optimization: it allows the comprehension to accumulate
1293+ // results in a mutable map instead of cloning and augmenting an unmodifiable
1294+ // map on every iteration.
1295+ options.enable_comprehension_mutable_map = true ;
1296+
1297+ ASSERT_OK_AND_ASSIGN (auto builder,
1298+ CreateStandardRuntimeBuilder (
1299+ internal::GetTestingDescriptorPool (), options));
1300+
1301+ ASSERT_THAT (extensions::RegisterComprehensionsV2Functions (
1302+ builder.function_registry (), options),
1303+ IsOk ());
1304+
1305+ ASSERT_OK_AND_ASSIGN (auto runtime, std::move (builder).Build ());
1306+
1307+ google::protobuf::Arena arena;
1308+ Activation activation;
1309+
1310+ auto map_builder = cel::NewMapValueBuilder (&arena);
1311+
1312+ int len = state.range (0 );
1313+ map_builder->Reserve (len);
1314+ for (int i = 0 ; i < len; i++) {
1315+ ASSERT_THAT (map_builder->Put (IntValue (i), IntValue (i)), IsOk ());
1316+ }
1317+
1318+ activation.InsertOrAssignValue (" map_var" , std::move (*map_builder).Build ());
1319+
1320+ ASSERT_OK_AND_ASSIGN (auto cel_expr, ProtobufRuntimeAdapter::CreateProgram (
1321+ *runtime, parsed_expr.parsed_expr ()));
1322+
1323+ for (auto _ : state) {
1324+ ASSERT_OK_AND_ASSIGN (cel::Value result,
1325+ cel_expr->Evaluate (&arena, activation));
1326+ ASSERT_TRUE (InstanceOf<MapValue>(result));
1327+ ASSERT_THAT (Cast<MapValue>(result).Size (), IsOkAndHolds (len));
1328+ }
1329+ }
1330+
1331+ BENCHMARK (BM_MapTransformComprehension)->Range (1 , 1 << 16 );
1332+
12731333} // namespace
12741334
12751335} // namespace cel
0 commit comments