mirror of
https://github.com/m5stack/esphome.git
synced 2026-05-20 11:52:52 -07:00
122 lines
3.6 KiB
C++
122 lines
3.6 KiB
C++
#include <benchmark/benchmark.h>
|
|
|
|
#include "esphome/components/number/number.h"
|
|
|
|
namespace esphome::benchmarks {
|
|
|
|
// Inner iteration count to amortize CodSpeed instrumentation overhead.
|
|
static constexpr int kInnerIterations = 2000;
|
|
|
|
// Minimal Number for benchmarking — control() publishes the value back.
|
|
class BenchNumber : public number::Number {
|
|
public:
|
|
void configure(const char *name) { this->configure_entity_(name, 0x12345678, 0); }
|
|
|
|
protected:
|
|
void control(float value) override { this->publish_state(value); }
|
|
};
|
|
|
|
// Helper to create a typical number entity for benchmarks.
|
|
static void setup_number(BenchNumber &number) {
|
|
number.configure("test_number");
|
|
number.traits.set_min_value(0.0f);
|
|
number.traits.set_max_value(100.0f);
|
|
number.traits.set_step(1.0f);
|
|
number.traits.set_mode(number::NUMBER_MODE_SLIDER);
|
|
}
|
|
|
|
// --- Number::publish_state() ---
|
|
// Measures the publish path: set_has_state, store value, callback dispatch.
|
|
|
|
static void NumberPublish_State(benchmark::State &state) {
|
|
BenchNumber number;
|
|
setup_number(number);
|
|
|
|
for (auto _ : state) {
|
|
for (int i = 0; i < kInnerIterations; i++) {
|
|
number.publish_state(static_cast<float>(i % 100));
|
|
}
|
|
benchmark::DoNotOptimize(number.state);
|
|
}
|
|
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
|
}
|
|
BENCHMARK(NumberPublish_State);
|
|
|
|
// --- Number::publish_state() with callback ---
|
|
// Measures callback dispatch overhead.
|
|
|
|
static void NumberPublish_WithCallback(benchmark::State &state) {
|
|
BenchNumber number;
|
|
setup_number(number);
|
|
|
|
uint64_t callback_count = 0;
|
|
number.add_on_state_callback([&callback_count](float) { callback_count++; });
|
|
|
|
for (auto _ : state) {
|
|
for (int i = 0; i < kInnerIterations; i++) {
|
|
number.publish_state(static_cast<float>(i % 100));
|
|
}
|
|
benchmark::DoNotOptimize(callback_count);
|
|
}
|
|
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
|
}
|
|
BENCHMARK(NumberPublish_WithCallback);
|
|
|
|
// --- NumberCall::perform() set value ---
|
|
// The most common number call — setting an absolute value.
|
|
// Exercises: validation against min/max, control() dispatch.
|
|
|
|
static void NumberCall_SetValue(benchmark::State &state) {
|
|
BenchNumber number;
|
|
setup_number(number);
|
|
number.publish_state(50.0f);
|
|
|
|
for (auto _ : state) {
|
|
for (int i = 0; i < kInnerIterations; i++) {
|
|
float val = static_cast<float>(i % 100);
|
|
number.make_call().set_value(val).perform();
|
|
}
|
|
benchmark::DoNotOptimize(number.state);
|
|
}
|
|
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
|
}
|
|
BENCHMARK(NumberCall_SetValue);
|
|
|
|
// --- NumberCall::perform() increment ---
|
|
// Exercises: state read, step arithmetic, max clamping.
|
|
|
|
static void NumberCall_Increment(benchmark::State &state) {
|
|
BenchNumber number;
|
|
setup_number(number);
|
|
number.publish_state(0.0f);
|
|
|
|
for (auto _ : state) {
|
|
for (int i = 0; i < kInnerIterations; i++) {
|
|
number.make_call().number_increment(true).perform();
|
|
}
|
|
benchmark::DoNotOptimize(number.state);
|
|
}
|
|
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
|
}
|
|
BENCHMARK(NumberCall_Increment);
|
|
|
|
// --- NumberCall::perform() decrement ---
|
|
// Exercises: state read, step arithmetic, min clamping.
|
|
|
|
static void NumberCall_Decrement(benchmark::State &state) {
|
|
BenchNumber number;
|
|
setup_number(number);
|
|
number.publish_state(100.0f);
|
|
|
|
for (auto _ : state) {
|
|
for (int i = 0; i < kInnerIterations; i++) {
|
|
number.make_call().number_decrement(true).perform();
|
|
}
|
|
benchmark::DoNotOptimize(number.state);
|
|
}
|
|
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
|
}
|
|
BENCHMARK(NumberCall_Decrement);
|
|
|
|
} // namespace esphome::benchmarks
|