From 9d303edaa84b02fc9655e179ed86fe553025a14c Mon Sep 17 00:00:00 2001 From: fancidev Date: Sat, 12 Jul 2025 17:45:52 +0800 Subject: [PATCH] Add caching for DataTable._get_row_renderables() --- src/textual/widgets/_data_table.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/textual/widgets/_data_table.py b/src/textual/widgets/_data_table.py index caf6e760f3..7841e3a769 100644 --- a/src/textual/widgets/_data_table.py +++ b/src/textual/widgets/_data_table.py @@ -749,6 +749,10 @@ def __init__( we need to re-render it. """ self._cell_render_cache: LRUCache[CellCacheKey, SegmentLines] = LRUCache(10000) """Cache for individual cells.""" + self._row_renderable_cache: LRUCache[tuple[int, int], RowRenderables] = ( + LRUCache(1000) + ) + """Caches row renderables - key is (update_count, row_index)""" self._line_cache: LRUCache[LineCacheKey, Strip] = LRUCache(1000) """Cache for lines within rows.""" self._offset_cache: LRUCache[int, list[tuple[RowKey, int]]] = LRUCache(1) @@ -1086,6 +1090,7 @@ def get_column_index(self, column_key: ColumnKey | str) -> int: def _clear_caches(self) -> None: self._row_render_cache.clear() self._cell_render_cache.clear() + self._row_renderable_cache.clear() self._line_cache.clear() self._styles_cache.clear() self._offset_cache.clear() @@ -1109,6 +1114,7 @@ def notify_style_update(self) -> None: super().notify_style_update() self._row_render_cache.clear() self._cell_render_cache.clear() + self._row_renderable_cache.clear() self._line_cache.clear() self._styles_cache.clear() self._get_styles_to_render_cell.cache_clear() @@ -1990,6 +1996,17 @@ def _get_row_renderables(self, row_index: int) -> RowRenderables: Returns: A RowRenderables containing the optional label and the rendered cells. """ + update_count = self._update_count + cache_key = (update_count, row_index) + if cache_key in self._row_renderable_cache: + row_renderables = self._row_renderable_cache[cache_key] + else: + row_renderables = self._compute_row_renderables(row_index) + self._row_renderable_cache[cache_key] = row_renderables + return row_renderables + + def _compute_row_renderables(self, row_index: int) -> RowRenderables: + """Actual computation for _get_row_renderables""" ordered_columns = self.ordered_columns if row_index == -1: header_row: list[RenderableType] = [