From 18b00fb3fcf3912ab660b54a2242a42292b05706 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 1 Apr 2026 09:51:55 -1000 Subject: [PATCH] =?UTF-8?q?[api]=20Revert=20push=5Fitem=20inline=20?= =?UTF-8?q?=E2=80=94=20CodSpeed=20shows=2046%=20regression?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inlining push_item into add_item bloated the dedup loop, causing the compiler to make worse inlining decisions. Total time went from 44µs to 64.5µs. Restore out-of-line with __attribute__((flatten)) which keeps add_item's dedup loop tight while still inlining push_back's callees into push_item. --- esphome/components/api/api_connection.cpp | 2 ++ esphome/components/api/api_connection.h | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 6bcaf52ba61..79df85ada35 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -2072,6 +2072,8 @@ void APIConnection::on_fatal_error() { this->flags_.remove = true; } +void __attribute__((flatten)) APIConnection::DeferredBatch::push_item(const BatchItem &item) { items.push_back(item); } + void APIConnection::DeferredBatch::add_item(EntityBase *entity, uint8_t message_type, uint8_t estimated_size, uint8_t aux_data_index) { // Check if we already have a message of this type for this entity diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index 3187a6df057..295346bb051 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -647,7 +647,10 @@ class APIConnection final : public APIServerConnectionBase { uint8_t aux_data_index = AUX_DATA_UNUSED); // Add item to the front of the batch (for high priority messages like ping) void add_item_front(EntityBase *entity, uint8_t message_type, uint8_t estimated_size); - void push_item(const BatchItem &item) { items.push_back(item); } + // Out-of-line with flatten: inlines push_back callees into push_item, + // but keeps push_item itself as a call from add_item. This prevents + // the compiler from bloating add_item's dedup loop and degrading icache. + void push_item(const BatchItem &item); // Clear all items void clear() {