blob: 50001a00575f70682988d17a6ea78c307620a713 [file] [log] [blame]
#include <algorithm>
#include <cstdint>
#include <memory>
#include <vector>
#include <benchmark/benchmark.h>
#include "absl/log/absl_check.h"
#include "google/protobuf/repeated_ptr_field.h"
#include "google/protobuf/rust/test/benchmarks/bench_data.pb.h"
#include "google/protobuf/rust/test/benchmarks/bench_data.upb.proto.h"
#include "protos/protos.h"
using benchmarks::BenchData;
#ifdef BENCHMARK_UPB
#define PROTO_BENCHMARK(NAME) EXTERN_BENCHMARK(NAME##_upb);
#else
#define PROTO_BENCHMARK(NAME) EXTERN_BENCHMARK(NAME##_cpp);
#endif
#define EXTERN_BENCHMARK(NAME) \
extern "C" { \
void NAME##_bench(); \
} \
void BM_##NAME(benchmark::State& state) { \
for (auto s : state) { \
NAME##_bench(); \
} \
} \
BENCHMARK(BM_##NAME);
void BM_set_string_cpp(benchmark::State& state) {
for (auto s : state) {
auto data = std::make_unique<BenchData>();
data->set_name(
"a relatively long string that will avoid any short string "
"optimizations.");
}
}
BENCHMARK(BM_set_string_cpp);
PROTO_BENCHMARK(set_string_rs);
void BM_set_int_cpp(benchmark::State& state) {
for (auto s : state) {
auto data = std::make_unique<BenchData>();
data->set_num2(123456789);
ABSL_CHECK_EQ(data->num2(), 123456789);
}
}
BENCHMARK(BM_set_int_cpp);
PROTO_BENCHMARK(set_int_rs);
extern "C" {
void benchmark_thunk_set_num2_rs(void* data, int32_t num2);
}
void BM_set_int_cpp_roundtrip(benchmark::State& state) {
for (auto s : state) {
auto data = std::make_unique<BenchData>();
benchmark_thunk_set_num2_rs((void*)data.get(), 123456789);
ABSL_CHECK_EQ(data->num2(), 123456789);
}
}
BENCHMARK(BM_set_int_cpp_roundtrip);
void BM_add_10_repeated_msg_copy_cpp(benchmark::State& state) {
for (auto s : state) {
auto data = std::make_unique<BenchData>();
for (int i = 0; i < 10; ++i) {
auto sub_data = std::make_unique<BenchData>();
sub_data->set_num2(i);
*data->add_subs() = *sub_data;
}
}
}
BENCHMARK(BM_add_10_repeated_msg_copy_cpp);
PROTO_BENCHMARK(add_10_repeated_msg_rs);
void BM_add_10_repeated_msg_direct_cpp(benchmark::State& state) {
for (auto s : state) {
auto data = std::make_unique<BenchData>();
for (int i = 0; i < 10; ++i) {
auto sub_data = data->add_subs();
sub_data->set_num2(i);
}
}
}
BENCHMARK(BM_add_10_repeated_msg_direct_cpp);
void BM_copy_from_10_repeated_msg_cpp(benchmark::State& state) {
auto source = std::make_unique<BenchData>();
for (int i = 0; i < 10; ++i) {
auto sub_data = source->add_subs();
sub_data->set_num2(i);
}
for (auto s : state) {
benchmarks::BenchData data;
*data.mutable_subs() = source->subs();
}
}
BENCHMARK(BM_copy_from_10_repeated_msg_cpp);
void BM_back_inserter_from_10_repeated_msg_cpp(benchmark::State& state) {
auto source = std::make_unique<BenchData>();
for (int i = 0; i < 10; ++i) {
auto sub_data = source->add_subs();
sub_data->set_num2(i);
}
for (auto s : state) {
benchmarks::BenchData data;
std::copy(source->subs().begin(), source->subs().end(),
google::protobuf::RepeatedFieldBackInserter(data.mutable_subs()));
}
}
BENCHMARK(BM_back_inserter_from_10_repeated_msg_cpp);
PROTO_BENCHMARK(copy_from_10_repeated_msg_rs);
PROTO_BENCHMARK(extend_10_repeated_msg_rs);
void BM_add_100_ints_cpp(benchmark::State& state) {
for (auto s : state) {
auto data = std::make_unique<BenchData>();
for (int i = 0; i < 100; ++i) {
data->mutable_nums()->Add(i);
}
}
}
BENCHMARK(BM_add_100_ints_cpp);
void BM_add_100_ints_upb(benchmark::State& state) {
for (auto s : state) {
::protos::Arena arena;
auto data = ::protos::CreateMessage<benchmarks::protos::BenchData>(arena);
for (int i = 0; i < 100; ++i) {
data.add_nums(i);
}
}
}
BENCHMARK(BM_add_100_ints_upb);
PROTO_BENCHMARK(add_100_ints_rs);
extern "C" {
void benchmark_thunk_add_num_rs(void* data, int32_t num);
}
void BM_add_100_ints_rs_roundtrip(benchmark::State& state) {
for (auto s : state) {
auto data = std::make_unique<BenchData>();
for (int i = 0; i < 100; ++i) {
benchmark_thunk_add_num_rs((void*)data.get(), i);
}
}
}
BENCHMARK(BM_add_100_ints_rs_roundtrip);
void BM_copy_from_100_ints_cpp(benchmark::State& state) {
auto source = std::make_unique<BenchData>();
for (int i = 0; i < 100; ++i) {
source->add_nums(i);
}
for (auto s : state) {
auto data = std::make_unique<BenchData>();
*data->mutable_nums() = source->nums();
ABSL_CHECK_EQ(data->nums()[99], 99);
}
}
BENCHMARK(BM_copy_from_100_ints_cpp);
void BM_copy_from_100_ints_upb(benchmark::State& state) {
::protos::Arena arena;
auto source = ::protos::CreateMessage<benchmarks::protos::BenchData>(arena);
for (int i = 0; i < 100; ++i) {
source.add_nums(i);
}
for (auto s : state) {
auto data = ::protos::CreateMessage<benchmarks::protos::BenchData>(arena);
data.resize_nums(source.nums_size());
std::copy(source.nums().begin(), source.nums().end(),
data.mutable_nums()->begin());
ABSL_CHECK_EQ(data.nums()[99], 99);
}
}
BENCHMARK(BM_copy_from_100_ints_upb);
PROTO_BENCHMARK(copy_from_100_ints_rs);
PROTO_BENCHMARK(extend_100_ints_rs);
EXTERN_BENCHMARK(extend_100_ints_vec_rs);
PROTO_BENCHMARK(sum_1000_ints_rs);
EXTERN_BENCHMARK(sum_1000_ints_vec_rs);
void BM_sum_1000_ints_cpp(benchmark::State& state) {
auto source = std::make_unique<BenchData>();
for (int i = 0; i < 1000; ++i) {
source->add_nums(i);
}
for (auto s : state) {
int sum = 0;
for (auto x : source->nums()) {
sum += x;
}
ABSL_CHECK_EQ(sum, 499500);
}
}
BENCHMARK(BM_sum_1000_ints_cpp);
void BM_sum_1000_ints_upb(benchmark::State& state) {
::protos::Arena arena;
auto data = ::protos::CreateMessage<benchmarks::protos::BenchData>(arena);
for (int i = 0; i < 1000; ++i) {
data.add_nums(i);
}
for (auto s : state) {
int sum = 0;
for (auto x : data.nums()) {
sum += x;
}
ABSL_CHECK_EQ(sum, 499500);
}
}
BENCHMARK(BM_sum_1000_ints_upb);
void BM_sum_1000_ints_vector(benchmark::State& state) {
std::vector<int32_t> nums;
nums.reserve(1000);
for (int i = 0; i < 1000; ++i) {
nums.push_back(i);
}
for (auto s : state) {
int sum = 0;
for (auto x : nums) {
sum += x;
}
ABSL_CHECK_EQ(sum, 499500);
}
}
BENCHMARK(BM_sum_1000_ints_vector);