diff --git a/script/test_helpers.py b/script/test_helpers.py index db1c981b82..24d99acaeb 100644 --- a/script/test_helpers.py +++ b/script/test_helpers.py @@ -139,6 +139,11 @@ def load_component_yaml_configs(components: list[str], tests_dir: Path) -> dict: Returns: Merged dict of component configs to add to the base config """ + # Note: components are processed in sorted order. For conflicting keys + # (e.g. two benchmark.yaml files both declaring sensor:), the first + # component alphabetically wins via setdefault(). This is fine for now + # with a single benchmark component (api) but would need a real merge + # strategy if multiple components declare overlapping configs. merged: dict = {} for component in components: yaml_path = tests_dir / component / BENCHMARK_YAML_FILENAME diff --git a/tests/benchmarks/components/.gitignore b/tests/benchmarks/components/.gitignore index d8b4157aef..163bec7b80 100644 --- a/tests/benchmarks/components/.gitignore +++ b/tests/benchmarks/components/.gitignore @@ -1,5 +1,2 @@ -# Gitignore settings for ESPHome -# This is an example and may include too much for your use-case. -# You can modify this file to suit your needs. /.esphome/ /secrets.yaml diff --git a/tests/benchmarks/components/api/bench_proto_encode.cpp b/tests/benchmarks/components/api/bench_proto_encode.cpp index c5dbd685be..11e4ccc4e3 100644 --- a/tests/benchmarks/components/api/bench_proto_encode.cpp +++ b/tests/benchmarks/components/api/bench_proto_encode.cpp @@ -70,7 +70,8 @@ static void CalcAndEncode_SensorStateResponse(benchmark::State &state) { } BENCHMARK(CalcAndEncode_SensorStateResponse); -// Cold path: fresh buffer each iteration (measures heap allocation) +// Cold path: fresh buffer each iteration (measures heap allocation). +// No inner loop — the point is to measure one alloc+encode per iteration. static void CalcAndEncode_SensorStateResponse_Fresh(benchmark::State &state) { SensorStateResponse msg; msg.key = 0x12345678; @@ -268,21 +269,19 @@ static void CalcAndEncode_DeviceInfoResponse(benchmark::State &state) { } BENCHMARK(CalcAndEncode_DeviceInfoResponse); -// Cold path: fresh buffer each iteration (measures heap allocation) +// Cold path: fresh buffer each iteration (measures heap allocation). +// No inner loop — the point is to measure one alloc+encode per iteration. static void CalcAndEncode_DeviceInfoResponse_Fresh(benchmark::State &state) { auto msg = make_device_info_response(); for (auto _ : state) { - for (int i = 0; i < kInnerIterations; i++) { - APIBuffer buffer; - uint32_t size = msg.calculate_size(); - buffer.resize(size); - ProtoWriteBuffer writer(&buffer, 0); - msg.encode(writer); - benchmark::DoNotOptimize(buffer.data()); - } + APIBuffer buffer; + uint32_t size = msg.calculate_size(); + buffer.resize(size); + ProtoWriteBuffer writer(&buffer, 0); + msg.encode(writer); + benchmark::DoNotOptimize(buffer.data()); } - state.SetItemsProcessed(state.iterations() * kInnerIterations); } BENCHMARK(CalcAndEncode_DeviceInfoResponse_Fresh);