From 1a0943c9604b77c643f076ea5722b6da00a07bba Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 9 Jul 2025 10:00:20 -1000 Subject: [PATCH] add component symbols --- esphome/analyze_memory.py | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/esphome/analyze_memory.py b/esphome/analyze_memory.py index 6bc0e0bebf..95ec0d2214 100644 --- a/esphome/analyze_memory.py +++ b/esphome/analyze_memory.py @@ -945,6 +945,9 @@ class MemoryAnalyzer: self._esphome_core_symbols: list[ tuple[str, str, int] ] = [] # Track core symbols + self._component_symbols: dict[str, list[tuple[str, str, int]]] = defaultdict( + list + ) # Track symbols for all components def analyze(self) -> dict[str, ComponentMemory]: """Analyze the ELF file and return component memory usage.""" @@ -1110,6 +1113,13 @@ class MemoryAnalyzer: demangled = self._demangle_symbol(symbol_name) self._esphome_core_symbols.append((symbol_name, demangled, size)) + # Track all component symbols for detailed analysis + if size > 0: + demangled = self._demangle_symbol(symbol_name) + self._component_symbols[component].append( + (symbol_name, demangled, size) + ) + def _identify_component(self, symbol_name: str) -> str: """Identify which component a symbol belongs to.""" # Demangle C++ names if needed @@ -1464,6 +1474,44 @@ class MemoryAnalyzer: lines.append("=" * table_width) + # Add detailed analysis for top 5 ESPHome components + esphome_components = [ + (name, mem) + for name, mem in components + if name.startswith("[esphome]") and name != "[esphome]core" + ] + top_esphome_components = sorted( + esphome_components, key=lambda x: x[1].flash_total, reverse=True + )[:5] + + if top_esphome_components: + for comp_name, comp_mem in top_esphome_components: + comp_symbols = self._component_symbols.get(comp_name, []) + if comp_symbols: + lines.append("") + lines.append("=" * table_width) + lines.append(f"{comp_name} Detailed Analysis".center(table_width)) + lines.append("=" * table_width) + lines.append("") + + # Sort symbols by size + sorted_symbols = sorted( + comp_symbols, key=lambda x: x[2], reverse=True + ) + + lines.append(f"Total symbols: {len(sorted_symbols)}") + lines.append(f"Total size: {comp_mem.flash_total:,} B") + lines.append("") + lines.append(f"Top 10 Largest {comp_name} Symbols:") + + MAX_SYMBOL_LENGTH = 80 + for i, (symbol, demangled, size) in enumerate(sorted_symbols[:10]): + lines.append( + f"{i + 1}. {demangled[:MAX_SYMBOL_LENGTH]} ({size:,} B)" + ) + + lines.append("=" * table_width) + return "\n".join(lines) def to_json(self) -> str: