[api] Move proxy message benchmarks into bench_proto_proxy.cpp

Splitting these out from bench_proto_encode.cpp and bench_proto_decode.cpp
moves them to the end of the linker's static-init order. CodSpeed's
callgrind runner has been segfaulting immediately after measuring the
last existing decode benchmark (Decode_SwitchCommandRequest), and
isolating the new code into its own translation unit lets us see whether
the crash is triggered by one of the new benchmarks or by something
about the new USE_*_PROXY/USE_INFRARED/USE_RADIO_FREQUENCY defines
changing how api_pb2.cpp compiles.
This commit is contained in:
J. Nick Koston
2026-04-29 21:38:01 -05:00
parent f841de0664
commit 483d294ef6
3 changed files with 287 additions and 308 deletions
@@ -384,128 +384,4 @@ BENCHMARK(CalcAndEncode_BLERawAdvs12_Fresh);
#endif // USE_BLUETOOTH_PROXY
// --- ZWaveProxyFrame (Z-Wave frame, ~16 bytes payload) ---
#ifdef USE_ZWAVE_PROXY
static constexpr uint8_t kZWaveFrameData[] = {0x01, 0x09, 0x00, 0x13, 0x01, 0x02, 0x00, 0x00,
0x25, 0x00, 0x05, 0xC4, 0x00, 0x00, 0x00, 0x00};
static ZWaveProxyFrame make_zwave_proxy_frame() {
ZWaveProxyFrame msg;
msg.data = kZWaveFrameData;
msg.data_len = sizeof(kZWaveFrameData);
return msg;
}
static void Encode_ZWaveProxyFrame(benchmark::State &state) {
auto msg = make_zwave_proxy_frame();
APIBuffer buffer;
buffer.resize(msg.calculate_size());
for (auto _ : state) {
for (int i = 0; i < kInnerIterations; i++) {
ProtoWriteBuffer writer(&buffer, 0);
msg.encode(writer);
}
benchmark::DoNotOptimize(buffer.data());
}
state.SetItemsProcessed(state.iterations() * kInnerIterations);
}
BENCHMARK(Encode_ZWaveProxyFrame);
#endif // USE_ZWAVE_PROXY
// --- SerialProxyDataReceived (serial passthrough, 64-byte payload) ---
#ifdef USE_SERIAL_PROXY
static constexpr size_t kSerialPayloadSize = 64;
static const uint8_t kSerialPayload[kSerialPayloadSize] = {
0x55, 0xAA, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB,
0xCD, 0xEF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE,
0xFF, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0,
0xF0, 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF};
static SerialProxyDataReceived make_serial_proxy_data_received() {
SerialProxyDataReceived msg;
msg.instance = 0;
msg.set_data(kSerialPayload, kSerialPayloadSize);
return msg;
}
static void Encode_SerialProxyDataReceived(benchmark::State &state) {
auto msg = make_serial_proxy_data_received();
APIBuffer buffer;
buffer.resize(msg.calculate_size());
for (auto _ : state) {
for (int i = 0; i < kInnerIterations; i++) {
ProtoWriteBuffer writer(&buffer, 0);
msg.encode(writer);
}
benchmark::DoNotOptimize(buffer.data());
}
state.SetItemsProcessed(state.iterations() * kInnerIterations);
}
BENCHMARK(Encode_SerialProxyDataReceived);
#endif // USE_SERIAL_PROXY
// --- InfraredRFReceiveEvent (100 timings, typical IR/RF capture) ---
#if defined(USE_IR_RF) || defined(USE_RADIO_FREQUENCY)
// Mark/space pairs simulating a typical RC-5 / NEC capture (100 timings).
static const std::vector<int32_t> &get_ir_timings_100() {
static std::vector<int32_t> *timings = nullptr;
if (timings == nullptr) {
timings = new std::vector<int32_t>();
timings->reserve(100);
for (int i = 0; i < 100; i++) {
timings->push_back((i % 2 == 0) ? 560 : -560);
}
}
return *timings;
}
static InfraredRFReceiveEvent make_infrared_rf_receive_event() {
InfraredRFReceiveEvent msg;
msg.key = 0xDEADBEEF;
msg.timings = &get_ir_timings_100();
return msg;
}
static void Encode_InfraredRFReceiveEvent(benchmark::State &state) {
auto msg = make_infrared_rf_receive_event();
APIBuffer buffer;
buffer.resize(msg.calculate_size());
for (auto _ : state) {
for (int i = 0; i < kInnerIterations; i++) {
ProtoWriteBuffer writer(&buffer, 0);
msg.encode(writer);
}
benchmark::DoNotOptimize(buffer.data());
}
state.SetItemsProcessed(state.iterations() * kInnerIterations);
}
BENCHMARK(Encode_InfraredRFReceiveEvent);
static void CalculateSize_InfraredRFReceiveEvent(benchmark::State &state) {
auto msg = make_infrared_rf_receive_event();
for (auto _ : state) {
uint32_t result = 0;
for (int i = 0; i < kInnerIterations; i++) {
result += msg.calculate_size();
}
benchmark::DoNotOptimize(result);
}
state.SetItemsProcessed(state.iterations() * kInnerIterations);
}
BENCHMARK(CalculateSize_InfraredRFReceiveEvent);
#endif // USE_IR_RF || USE_RADIO_FREQUENCY
} // namespace esphome::api::benchmarks