ESPHome 2026.3.3
Loading...
Searching...
No Matches
runtime_stats.cpp
Go to the documentation of this file.
1#include "runtime_stats.h"
2
3#ifdef USE_RUNTIME_STATS
4
6#include <algorithm>
7
8namespace esphome {
9
10namespace runtime_stats {
11
12RuntimeStatsCollector::RuntimeStatsCollector() : log_interval_(60000), next_log_time_(60000) {
14}
15
17 if (component == nullptr)
18 return;
19
20 // Record stats using component pointer as key
21 this->component_stats_[component].record_time(duration_us);
22}
23
25 // First pass: count active components
26 size_t count = 0;
27 for (const auto &it : this->component_stats_) {
28 if (it.second.get_period_count() > 0) {
29 count++;
30 }
31 }
32
33 ESP_LOGI(TAG,
34 "Component Runtime Statistics\n"
35 " Period stats (last %" PRIu32 "ms): %zu active components",
36 this->log_interval_, count);
37
38 if (count == 0) {
39 return;
40 }
41
42 // Stack buffer sized to actual active count (up to 256 components), heap fallback for larger
44 Component **sorted = buffer.get();
45
46 // Second pass: fill buffer with active components
47 size_t idx = 0;
48 for (const auto &it : this->component_stats_) {
49 if (it.second.get_period_count() > 0) {
50 sorted[idx++] = it.first;
51 }
52 }
53
54 // Sort by period runtime (descending)
55 std::sort(sorted, sorted + count, [this](Component *a, Component *b) {
56 return this->component_stats_[a].get_period_time_us() > this->component_stats_[b].get_period_time_us();
57 });
58
59 // Log top components by period runtime
60 for (size_t i = 0; i < count; i++) {
61 const auto &stats = this->component_stats_[sorted[i]];
62 ESP_LOGI(TAG, " %s: count=%" PRIu32 ", avg=%.3fms, max=%.2fms, total=%.1fms",
63 LOG_STR_ARG(sorted[i]->get_component_log_str()), stats.get_period_count(),
64 stats.get_period_avg_time_us() / 1000.0f, stats.get_period_max_time_us() / 1000.0f,
65 stats.get_period_time_us() / 1000.0f);
66 }
67
68 // Log total stats since boot (only for active components - idle ones haven't changed)
69 ESP_LOGI(TAG, " Total stats (since boot): %zu active components", count);
70
71 // Re-sort by total runtime for all-time stats
72 std::sort(sorted, sorted + count, [this](Component *a, Component *b) {
73 return this->component_stats_[a].get_total_time_us() > this->component_stats_[b].get_total_time_us();
74 });
75
76 for (size_t i = 0; i < count; i++) {
77 const auto &stats = this->component_stats_[sorted[i]];
78 ESP_LOGI(TAG, " %s: count=%" PRIu32 ", avg=%.3fms, max=%.2fms, total=%.1fms",
79 LOG_STR_ARG(sorted[i]->get_component_log_str()), stats.get_total_count(),
80 stats.get_total_avg_time_us() / 1000.0f, stats.get_total_max_time_us() / 1000.0f,
81 stats.get_total_time_us() / 1000.0);
82 }
83}
84
86 if ((int32_t) (current_time - this->next_log_time_) >= 0) {
87 this->log_stats_();
88 this->reset_stats_();
89 this->next_log_time_ = current_time + this->log_interval_;
90 }
91}
92
93} // namespace runtime_stats
94
96 nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
97
98} // namespace esphome
99
100#endif // USE_RUNTIME_STATS
Helper class for efficient buffer allocation - uses stack for small sizes, heap for large This is use...
Definition helpers.h:558
void record_component_time(Component *component, uint32_t duration_us)
std::map< Component *, ComponentRuntimeStats > component_stats_
void process_pending_stats(uint32_t current_time)
const Component * component
Definition component.cpp:37
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
runtime_stats::RuntimeStatsCollector * global_runtime_stats
static void uint32_t