From ea32fbb51d267b6cbd9eaec223fbeffa37b4ae3d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 13 Apr 2026 17:20:04 -1000 Subject: [PATCH] [light] Force-inline ColorModeBitPolicy::to_bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although to_bit is constexpr and header-defined, the compiler leaves it as an out-of-line function when called with a runtime ColorMode, costing a call0/call8 for what is a short linear search over a 10-entry compile-time table. Marking it ESPHOME_ALWAYS_INLINE lets the compiler fold the lookup into each caller (validate_, color_mode_to_human, get_suitable_color_modes_mask_, light_json_schema). The to_bit symbol disappears from the link output entirely. Flash delta is small (+16 B ESP8266, +44 B ESP32-IDF in isolated light build); the intent is the runtime win — CodSpeed will quantify it. --- esphome/components/light/color_mode.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esphome/components/light/color_mode.h b/esphome/components/light/color_mode.h index 0750ae250d..a892bd81b8 100644 --- a/esphome/components/light/color_mode.h +++ b/esphome/components/light/color_mode.h @@ -2,6 +2,7 @@ #include #include "esphome/core/finite_set_mask.h" +#include "esphome/core/helpers.h" // ESPHOME_ALWAYS_INLINE namespace esphome::light { @@ -128,7 +129,7 @@ struct ColorModeBitPolicy { using mask_t = uint16_t; // 10 bits requires uint16_t static constexpr int MAX_BITS = sizeof(COLOR_MODE_LOOKUP) / sizeof(COLOR_MODE_LOOKUP[0]); - static constexpr unsigned to_bit(ColorMode mode) { + static constexpr unsigned ESPHOME_ALWAYS_INLINE to_bit(ColorMode mode) { // Linear search through lookup table // Compiler optimizes this to efficient code since array is constexpr for (int i = 0; i < MAX_BITS; ++i) {