From 36a598fa40e16f49ec6eba5cc5ebef6e23f39b7b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 3 Mar 2026 22:22:51 -1000 Subject: [PATCH] [core] Call loop() directly in main loop, bypass call() indirection In the main loop, components in looping_components_ active section are guaranteed to be in LOOP state. The call() method's state machine dispatch (checking CONSTRUCTION, SETUP, FAILED, LOOP_DONE) is only needed during Application::setup(). In the main loop it adds two unnecessary function call frames per component per iteration (call() -> call_loop_() -> loop()). This became dead weight when looping_components_ partitioning was introduced in June 2025 (8a06c4380d). Before that, Application::loop() iterated components_[] which contained all states, so the state check was necessary. --- esphome/core/application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/core/application.cpp b/esphome/core/application.cpp index 8c2ba58c86..f827783503 100644 --- a/esphome/core/application.cpp +++ b/esphome/core/application.cpp @@ -173,7 +173,7 @@ void Application::loop() { { this->set_current_component(component); WarnIfComponentBlockingGuard guard{component, last_op_end_time}; - component->call(); + component->loop(); // Use the finish method to get the current time as the end time last_op_end_time = guard.finish(); }