mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
We now test each field type separately, and benchmark them separately too. PiperOrigin-RevId: 764546791
84 lines
2.8 KiB
C++
84 lines
2.8 KiB
C++
// Protocol Buffers - Google's data interchange format
|
|
// Copyright 2025 Google LLC. All rights reserved.
|
|
//
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file or at
|
|
// https://developers.google.com/open-source/licenses/bsd
|
|
|
|
#include <cstddef>
|
|
#include <string>
|
|
#include <type_traits>
|
|
#include <vector>
|
|
|
|
#include <benchmark/benchmark.h>
|
|
#include <gtest/gtest.h>
|
|
#include "absl/container/flat_hash_set.h"
|
|
#include "upb/mem/alloc.h"
|
|
#include "upb/mem/arena.h"
|
|
#include "upb/message/message.h"
|
|
#include "upb/mini_table/message.h"
|
|
#include "upb/wire/decode.h"
|
|
#include "upb/wire/decode_fast/combinations.h"
|
|
#include "upb/wire/test_util/field_types.h"
|
|
#include "upb/wire/test_util/make_mini_table.h"
|
|
#include "upb/wire/test_util/wire_message.h"
|
|
|
|
// Must be last.
|
|
#include "upb/port/def.inc"
|
|
|
|
namespace upb {
|
|
namespace test {
|
|
|
|
namespace {
|
|
|
|
void BM_Decode(benchmark::State& state, const upb_MiniTable* mt,
|
|
std::string payload, bool alias, bool initial_block) {
|
|
char mem[4096];
|
|
int decode_options = 0;
|
|
for (auto s : state) {
|
|
upb_Arena* arena = initial_block
|
|
? upb_Arena_Init(mem, 4096, &upb_alloc_global)
|
|
: upb_Arena_New();
|
|
upb_Message* msg = upb_Message_New(mt, arena);
|
|
upb_DecodeStatus result = upb_Decode(payload.data(), payload.size(), msg,
|
|
mt, nullptr, decode_options, arena);
|
|
ASSERT_EQ(result, kUpb_DecodeStatus_Ok) << upb_DecodeStatus_String(result);
|
|
upb_Arena_Free(arena);
|
|
}
|
|
state.SetBytesProcessed(state.iterations() * payload.size());
|
|
}
|
|
|
|
[[maybe_unused]] upb_Arena* benchmark_registration = [] {
|
|
upb_Arena* arena = upb_Arena_New();
|
|
std::vector<size_t> sizes{8, 64, 512};
|
|
for (size_t size : sizes) {
|
|
absl::flat_hash_set<upb_DecodeFast_Type> fast_types;
|
|
ForEachType([&](auto&& type) {
|
|
using Type = std::remove_reference_t<decltype(type)>;
|
|
// We only need to benchmark each wire type once, since they are all
|
|
// treated the same by the decoder.
|
|
if (!fast_types.insert(Type::kFastType).second) return;
|
|
std::vector<bool> initial_block{true, false};
|
|
for (bool init : initial_block) {
|
|
auto [mt, field] = MiniTable::MakeSingleFieldTable<Type>(
|
|
1, kUpb_DecodeFast_Scalar, arena);
|
|
std::string payload;
|
|
while (payload.size() < size) {
|
|
payload.append(ToBinaryPayload(wire_types::WireMessage{
|
|
{1, Type::WireValue(typename Type::Value{})}}));
|
|
}
|
|
::benchmark::RegisterBenchmark(
|
|
absl::StrFormat("BM_Decode/%s/%zu/%s", Type::kName, size,
|
|
init ? "InitialBlock" : "NoInitialBlock")
|
|
.c_str(),
|
|
BM_Decode, mt, payload, false, init);
|
|
}
|
|
});
|
|
}
|
|
return arena;
|
|
}();
|
|
|
|
} // namespace
|
|
|
|
} // namespace test
|
|
} // namespace upb
|