<commit_before>#include "benchmark/benchmark.h"

#include "google/api/expr/v1alpha1/syntax.pb.h"
#include "google/protobuf/text_format.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
#include "absl/strings/match.h"
#include "eval/public/activation.h"
#include "eval/public/builtin_func_registrar.h"
#include "eval/public/cel_expr_builder_factory.h"
#include "eval/public/cel_expression.h"
#include "eval/public/cel_value.h"
#include "eval/public/containers/container_backed_list_impl.h"
#include "eval/public/structs/cel_proto_wrapper.h"
#include "eval/tests/request_context.pb.h"

namespace google {
namespace api {
namespace expr {
namespace runtime {

namespace {

using google::api::expr::v1alpha1::Expr;
using google::api::expr::v1alpha1::SourceInfo;

// Benchmark test
// Evaluates cel expression:
// '1 + 1 + 1 .... +1'
static void BM_Eval(benchmark::State& state) {
  auto builder = CreateCelExpressionBuilder();
  auto reg_status = RegisterBuiltinFunctions(builder->GetRegistry());
  CHECK_OK(reg_status);

  int len = state.range(0);

  Expr root_expr;
  Expr* cur_expr = &root_expr;

  for (int i = 0; i < len; i++) {
    Expr::Call* call = cur_expr->mutable_call_expr();
    call->set_function("_+_");
    call->add_args()->mutable_const_expr()->set_int64_value(1);
    cur_expr = call->add_args();
  }

  cur_expr->mutable_const_expr()->set_int64_value(1);

  SourceInfo source_info;
  auto cel_expr_status = builder->CreateExpression(&root_expr, &source_info);
  CHECK_OK(cel_expr_status.status());

  std::unique_ptr<CelExpression> cel_expr = std::move(cel_expr_status.value());

  for (auto _ : state) {
    google::protobuf::Arena arena;
    Activation activation;
    auto eval_result = cel_expr->Evaluate(activation, &arena);
    CHECK_OK(eval_result.status());

    CelValue result = eval_result.value();
    GOOGLE_CHECK(result.IsInt64());
    GOOGLE_CHECK(result.Int64OrDie() == len + 1);
  }
}

BENCHMARK(BM_Eval)->Range(1, 32768);

std::string CELAstFlattenedMap() {
  return R"(
call_expr: <<commit_msg>Add a benchmark to measure string concatenation. This should guide the impact of non-arena string allocations.<commit_after>#include "benchmark/benchmark.h"

#include "google/api/expr/v1alpha1/syntax.pb.h"
#include "google/protobuf/text_format.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
#include "absl/strings/match.h"
#include "eval/public/activation.h"
#include "eval/public/builtin_func_registrar.h"
#include "eval/public/cel_expr_builder_factory.h"
#include "eval/public/cel_expression.h"
#include "eval/public/cel_value.h"
#include "eval/public/containers/container_backed_list_impl.h"
#include "eval/public/structs/cel_proto_wrapper.h"
#include "eval/tests/request_context.pb.h"

namespace google {
namespace api {
namespace expr {
namespace runtime {

namespace {

using google::api::expr::v1alpha1::Expr;
using google::api::expr::v1alpha1::SourceInfo;

// Benchmark test
// Evaluates cel expression:
// '1 + 1 + 1 .... +1'
static void BM_Eval(benchmark::State& state) {
  auto builder = CreateCelExpressionBuilder();
  auto reg_status = RegisterBuiltinFunctions(builder->GetRegistry());
  CHECK_OK(reg_status);

  int len = state.range(0);

  Expr root_expr;
  Expr* cur_expr = &root_expr;

  for (int i = 0; i < len; i++) {
    Expr::Call* call = cur_expr->mutable_call_expr();
    call->set_function("_+_");
    call->add_args()->mutable_const_expr()->set_int64_value(1);
    cur_expr = call->add_args();
  }

  cur_expr->mutable_const_expr()->set_int64_value(1);

  SourceInfo source_info;
  auto cel_expr_status = builder->CreateExpression(&root_expr, &source_info);
  CHECK_OK(cel_expr_status.status());

  std::unique_ptr<CelExpression> cel_expr = std::move(cel_expr_status.value());

  for (auto _ : state) {
    google::protobuf::Arena arena;
    Activation activation;
    auto eval_result = cel_expr->Evaluate(activation, &arena);
    CHECK_OK(eval_result.status());

    CelValue result = eval_result.value();
    GOOGLE_CHECK(result.IsInt64());
    GOOGLE_CHECK(result.Int64OrDie() == len + 1);
  }
}

BENCHMARK(BM_Eval)->Range(1, 32768);

// Benchmark test
// Evaluates cel expression:
// '"a" + "a" + "a" .... + "a"'
static void BM_EvalString(benchmark::State& state) {
  auto builder = CreateCelExpressionBuilder();
  auto reg_status = RegisterBuiltinFunctions(builder->GetRegistry());
  CHECK_OK(reg_status);

  int len = state.range(0);

  Expr root_expr;
  Expr* cur_expr = &root_expr;

  for (int i = 0; i < len; i++) {
    Expr::Call* call = cur_expr->mutable_call_expr();
    call->set_function("_+_");
    call->add_args()->mutable_const_expr()->set_string_value("a");
    cur_expr = call->add_args();
  }

  cur_expr->mutable_const_expr()->set_string_value("a");

  SourceInfo source_info;
  auto cel_expr_status = builder->CreateExpression(&root_expr, &source_info);
  CHECK_OK(cel_expr_status.status());

  std::unique_ptr<CelExpression> cel_expr = std::move(cel_expr_status.value());

  for (auto _ : state) {
    google::protobuf::Arena arena;
    Activation activation;
    auto eval_result = cel_expr->Evaluate(activation, &arena);
    CHECK_OK(eval_result.status());

    CelValue result = eval_result.value();
    GOOGLE_CHECK(result.IsString());
    GOOGLE_CHECK(result.StringOrDie().value().size() == len + 1);
  }
}

BENCHMARK(BM_EvalString)->Range(1, 32768);

std::string CELAstFlattenedMap() {
  return R"(
call_expr: <
{'fraction_non_alphanumeric': 0.15199123127511874, 'fraction_numerical': 0.012239678480087687, 'mean_word_length': 5.186440677966102, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6691193', 'n_tokens_mistral': 1986, 'n_tokens_neox': 1902, 'n_words': 333}