mirror of
https://github.com/esphome/esphome.git
synced 2026-10-05 10:31:29 +00:00
[api] Drop escape() helper and return-by-value APIBuffer in proxy decode benchmarks
Simplifies the decode benchmarks to mirror the encode pattern more closely: no per-iteration asm volatile barrier, no return-by-value of APIBuffer through encode_message_for_proxy. CodSpeed callgrind has been crashing inside Decode_ZWaveProxyFrame and the previous setup was the main thing it had that the (passing) Encode_ZWaveProxyFrame did not.
This commit is contained in:
@@ -13,17 +13,14 @@ namespace esphome::api::benchmarks {
|
|||||||
|
|
||||||
static constexpr int kInnerIterations = 2000;
|
static constexpr int kInnerIterations = 2000;
|
||||||
|
|
||||||
template<typename T> static APIBuffer encode_message_for_proxy(const T &msg) {
|
// Encodes `src` into `out`. Caller owns `out` and must keep it alive across
|
||||||
APIBuffer buffer;
|
// the decode loop (decoded messages may store pointers back into its bytes).
|
||||||
uint32_t size = msg.calculate_size();
|
template<typename T> static void encode_into(APIBuffer &out, const T &src) {
|
||||||
buffer.resize(size);
|
out.resize(src.calculate_size());
|
||||||
ProtoWriteBuffer writer(&buffer, 0);
|
ProtoWriteBuffer writer(&out, 0);
|
||||||
msg.encode(writer);
|
src.encode(writer);
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void escape_proxy(void *p) { asm volatile("" : : "g"(p) : "memory"); }
|
|
||||||
|
|
||||||
// --- ZWaveProxyFrame (Z-Wave frame, ~16 bytes payload) ---
|
// --- ZWaveProxyFrame (Z-Wave frame, ~16 bytes payload) ---
|
||||||
|
|
||||||
#ifdef USE_ZWAVE_PROXY
|
#ifdef USE_ZWAVE_PROXY
|
||||||
@@ -53,18 +50,16 @@ static void Decode_ZWaveProxyFrame(benchmark::State &state) {
|
|||||||
ZWaveProxyFrame source;
|
ZWaveProxyFrame source;
|
||||||
source.data = kZWaveFrameData;
|
source.data = kZWaveFrameData;
|
||||||
source.data_len = sizeof(kZWaveFrameData);
|
source.data_len = sizeof(kZWaveFrameData);
|
||||||
auto encoded = encode_message_for_proxy(source);
|
APIBuffer encoded;
|
||||||
auto *data = encoded.data();
|
encode_into(encoded, source);
|
||||||
auto size = encoded.size();
|
const uint8_t *data = encoded.data();
|
||||||
benchmark::DoNotOptimize(data);
|
size_t size = encoded.size();
|
||||||
benchmark::DoNotOptimize(size);
|
|
||||||
|
|
||||||
for (auto _ : state) {
|
for (auto _ : state) {
|
||||||
for (int i = 0; i < kInnerIterations; i++) {
|
for (int i = 0; i < kInnerIterations; i++) {
|
||||||
ZWaveProxyFrame msg;
|
ZWaveProxyFrame msg;
|
||||||
escape_proxy(&msg);
|
|
||||||
msg.decode(data, size);
|
msg.decode(data, size);
|
||||||
escape_proxy(&msg);
|
benchmark::DoNotOptimize(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
||||||
@@ -78,18 +73,16 @@ static void Decode_ZWaveProxyRequest(benchmark::State &state) {
|
|||||||
source.type = enums::ZWAVE_PROXY_REQUEST_TYPE_HOME_ID_CHANGE;
|
source.type = enums::ZWAVE_PROXY_REQUEST_TYPE_HOME_ID_CHANGE;
|
||||||
source.data = kZWaveRequestData;
|
source.data = kZWaveRequestData;
|
||||||
source.data_len = sizeof(kZWaveRequestData);
|
source.data_len = sizeof(kZWaveRequestData);
|
||||||
auto encoded = encode_message_for_proxy(source);
|
APIBuffer encoded;
|
||||||
auto *data = encoded.data();
|
encode_into(encoded, source);
|
||||||
auto size = encoded.size();
|
const uint8_t *data = encoded.data();
|
||||||
benchmark::DoNotOptimize(data);
|
size_t size = encoded.size();
|
||||||
benchmark::DoNotOptimize(size);
|
|
||||||
|
|
||||||
for (auto _ : state) {
|
for (auto _ : state) {
|
||||||
for (int i = 0; i < kInnerIterations; i++) {
|
for (int i = 0; i < kInnerIterations; i++) {
|
||||||
ZWaveProxyRequest msg;
|
ZWaveProxyRequest msg;
|
||||||
escape_proxy(&msg);
|
|
||||||
msg.decode(data, size);
|
msg.decode(data, size);
|
||||||
escape_proxy(&msg);
|
benchmark::DoNotOptimize(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
||||||
@@ -135,18 +128,16 @@ static void Decode_SerialProxyWriteRequest(benchmark::State &state) {
|
|||||||
SerialProxyDataReceived source;
|
SerialProxyDataReceived source;
|
||||||
source.instance = 0;
|
source.instance = 0;
|
||||||
source.set_data(kSerialPayload, kSerialPayloadSize);
|
source.set_data(kSerialPayload, kSerialPayloadSize);
|
||||||
auto encoded = encode_message_for_proxy(source);
|
APIBuffer encoded;
|
||||||
auto *data = encoded.data();
|
encode_into(encoded, source);
|
||||||
auto size = encoded.size();
|
const uint8_t *data = encoded.data();
|
||||||
benchmark::DoNotOptimize(data);
|
size_t size = encoded.size();
|
||||||
benchmark::DoNotOptimize(size);
|
|
||||||
|
|
||||||
for (auto _ : state) {
|
for (auto _ : state) {
|
||||||
for (int i = 0; i < kInnerIterations; i++) {
|
for (int i = 0; i < kInnerIterations; i++) {
|
||||||
SerialProxyWriteRequest msg;
|
SerialProxyWriteRequest msg;
|
||||||
escape_proxy(&msg);
|
|
||||||
msg.decode(data, size);
|
msg.decode(data, size);
|
||||||
escape_proxy(&msg);
|
benchmark::DoNotOptimize(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
||||||
@@ -265,17 +256,14 @@ static APIBuffer build_infrared_rf_transmit_wire() {
|
|||||||
|
|
||||||
static void Decode_InfraredRFTransmitRawTimingsRequest(benchmark::State &state) {
|
static void Decode_InfraredRFTransmitRawTimingsRequest(benchmark::State &state) {
|
||||||
auto encoded = build_infrared_rf_transmit_wire();
|
auto encoded = build_infrared_rf_transmit_wire();
|
||||||
auto *data = encoded.data();
|
const uint8_t *data = encoded.data();
|
||||||
auto size = encoded.size();
|
size_t size = encoded.size();
|
||||||
benchmark::DoNotOptimize(data);
|
|
||||||
benchmark::DoNotOptimize(size);
|
|
||||||
|
|
||||||
for (auto _ : state) {
|
for (auto _ : state) {
|
||||||
for (int i = 0; i < kInnerIterations; i++) {
|
for (int i = 0; i < kInnerIterations; i++) {
|
||||||
InfraredRFTransmitRawTimingsRequest msg;
|
InfraredRFTransmitRawTimingsRequest msg;
|
||||||
escape_proxy(&msg);
|
|
||||||
msg.decode(data, size);
|
msg.decode(data, size);
|
||||||
escape_proxy(&msg);
|
benchmark::DoNotOptimize(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
||||||
|
|||||||
Reference in New Issue
Block a user