diff --git a/esphome/core/runtime_stats.cpp b/esphome/core/runtime_stats.cpp deleted file mode 100644 index da19349537..0000000000 --- a/esphome/core/runtime_stats.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "esphome/core/runtime_stats.h" -#include "esphome/core/component.h" -#include - -namespace esphome { - -RuntimeStatsCollector runtime_stats; - -void RuntimeStatsCollector::record_component_time(Component *component, uint32_t duration_ms, uint32_t current_time) { - if (!this->enabled_ || component == nullptr) - return; - - // Check if we have cached the name for this component - auto name_it = this->component_names_cache_.find(component); - if (name_it == this->component_names_cache_.end()) { - // First time seeing this component, cache its name - const char *source = component->get_component_source(); - this->component_names_cache_[component] = source; - this->component_stats_[source].record_time(duration_ms); - } else { - // Use cached name - no string operations, just map lookup - this->component_stats_[name_it->second].record_time(duration_ms); - } - - // If next_log_time_ is 0, initialize it - if (this->next_log_time_ == 0) { - this->next_log_time_ = current_time + this->log_interval_; - return; - } - - // Don't print stats here anymore - let process_pending_stats handle it -} - -void RuntimeStatsCollector::log_stats_() { - ESP_LOGI(RUNTIME_TAG, "Component Runtime Statistics"); - ESP_LOGI(RUNTIME_TAG, "Period stats (last %" PRIu32 "ms):", this->log_interval_); - - // First collect stats we want to display - std::vector stats_to_display; - - for (const auto &it : this->component_stats_) { - const ComponentRuntimeStats &stats = it.second; - if (stats.get_period_count() > 0) { - ComponentStatPair pair = {it.first, &stats}; - stats_to_display.push_back(pair); - } - } - - // Sort by period runtime (descending) - std::sort(stats_to_display.begin(), stats_to_display.end(), std::greater()); - - // Log top components by period runtime - for (const auto &it : stats_to_display) { - const std::string &source = it.name; - const ComponentRuntimeStats *stats = it.stats; - - ESP_LOGI(RUNTIME_TAG, " %s: count=%" PRIu32 ", avg=%.2fms, max=%" PRIu32 "ms, total=%" PRIu32 "ms", source.c_str(), - stats->get_period_count(), stats->get_period_avg_time_ms(), stats->get_period_max_time_ms(), - stats->get_period_time_ms()); - } - - // Log total stats since boot - ESP_LOGI(RUNTIME_TAG, "Total stats (since boot):"); - - // Re-sort by total runtime for all-time stats - std::sort(stats_to_display.begin(), stats_to_display.end(), - [](const ComponentStatPair &a, const ComponentStatPair &b) { - return a.stats->get_total_time_ms() > b.stats->get_total_time_ms(); - }); - - for (const auto &it : stats_to_display) { - const std::string &source = it.name; - const ComponentRuntimeStats *stats = it.stats; - - ESP_LOGI(RUNTIME_TAG, " %s: count=%" PRIu32 ", avg=%.2fms, max=%" PRIu32 "ms, total=%" PRIu32 "ms", source.c_str(), - stats->get_total_count(), stats->get_total_avg_time_ms(), stats->get_total_max_time_ms(), - stats->get_total_time_ms()); - } -} - -void RuntimeStatsCollector::process_pending_stats(uint32_t current_time) { - if (!this->enabled_ || this->next_log_time_ == 0) - return; - - if (current_time >= this->next_log_time_) { - this->log_stats_(); - this->reset_stats_(); - this->next_log_time_ = current_time + this->log_interval_; - } -} - -} // namespace esphome diff --git a/esphome/core/runtime_stats.h b/esphome/core/runtime_stats.h deleted file mode 100644 index 6ae80750a6..0000000000 --- a/esphome/core/runtime_stats.h +++ /dev/null @@ -1,121 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include "esphome/core/helpers.h" -#include "esphome/core/log.h" - -namespace esphome { - -static const char *const RUNTIME_TAG = "runtime"; - -class Component; // Forward declaration - -class ComponentRuntimeStats { - public: - ComponentRuntimeStats() - : period_count_(0), - total_count_(0), - period_time_ms_(0), - total_time_ms_(0), - period_max_time_ms_(0), - total_max_time_ms_(0) {} - - void record_time(uint32_t duration_ms) { - // Update period counters - this->period_count_++; - this->period_time_ms_ += duration_ms; - if (duration_ms > this->period_max_time_ms_) - this->period_max_time_ms_ = duration_ms; - - // Update total counters - this->total_count_++; - this->total_time_ms_ += duration_ms; - if (duration_ms > this->total_max_time_ms_) - this->total_max_time_ms_ = duration_ms; - } - - void reset_period_stats() { - this->period_count_ = 0; - this->period_time_ms_ = 0; - this->period_max_time_ms_ = 0; - } - - // Period stats (reset each logging interval) - uint32_t get_period_count() const { return this->period_count_; } - uint32_t get_period_time_ms() const { return this->period_time_ms_; } - uint32_t get_period_max_time_ms() const { return this->period_max_time_ms_; } - float get_period_avg_time_ms() const { - return this->period_count_ > 0 ? this->period_time_ms_ / static_cast(this->period_count_) : 0.0f; - } - - // Total stats (persistent until reboot) - uint32_t get_total_count() const { return this->total_count_; } - uint32_t get_total_time_ms() const { return this->total_time_ms_; } - uint32_t get_total_max_time_ms() const { return this->total_max_time_ms_; } - float get_total_avg_time_ms() const { - return this->total_count_ > 0 ? this->total_time_ms_ / static_cast(this->total_count_) : 0.0f; - } - - protected: - // Period stats (reset each logging interval) - uint32_t period_count_; - uint32_t period_time_ms_; - uint32_t period_max_time_ms_; - - // Total stats (persistent until reboot) - uint32_t total_count_; - uint32_t total_time_ms_; - uint32_t total_max_time_ms_; -}; - -// For sorting components by run time -struct ComponentStatPair { - std::string name; - const ComponentRuntimeStats *stats; - - bool operator>(const ComponentStatPair &other) const { - // Sort by period time as that's what we're displaying in the logs - return stats->get_period_time_ms() > other.stats->get_period_time_ms(); - } -}; - -class RuntimeStatsCollector { - public: - RuntimeStatsCollector() : log_interval_(60000), next_log_time_(0), enabled_(true) {} - - void set_log_interval(uint32_t log_interval) { this->log_interval_ = log_interval; } - uint32_t get_log_interval() const { return this->log_interval_; } - - void set_enabled(bool enabled) { this->enabled_ = enabled; } - bool is_enabled() const { return this->enabled_; } - - void record_component_time(Component *component, uint32_t duration_ms, uint32_t current_time); - - // Process any pending stats printing (should be called after component loop) - void process_pending_stats(uint32_t current_time); - - protected: - void log_stats_(); - - void reset_stats_() { - for (auto &it : this->component_stats_) { - it.second.reset_period_stats(); - } - } - - // Back to string keys, but we'll cache the source name per component - std::map component_stats_; - std::map component_names_cache_; - uint32_t log_interval_; - uint32_t next_log_time_; - bool enabled_; -}; - -// Global instance for runtime stats collection -extern RuntimeStatsCollector runtime_stats; - -} // namespace esphome \ No newline at end of file