perf(grid): rebuild only the rows and cells whose inputs changed (#972) - #973
Merged
Merged
Conversation
#972) A staged cell edit rebuilt every visible row, and each row rebuilt all of its cells; a function-level profile showed ~67% of frame time in that rebuild and ~25% in per-cell inherited lookups. Panning also rebuilt the whole window on every column boundary. - VirtualResultGrid keeps the last _DataRow per visual row and hands the framework the same instance when a rebuild would produce an identical row; _DataRow keeps the same per column for _GridCell (keyed by column). Widgets cannot override ==, so reuse is by instance with a sameAs comparison. - Selection and editing cell are clipped to the row they touch, so a selection change no longer invalidates every row. - DataGridStagingBuffer.rowRenderSignature fingerprints the staged state that affects drawing a row (status and modified cells). - The column window is kept until the viewport reaches its edge, with a wider overscan (6), so it is rebuilt every few columns instead of on each one. - Add benchmark/grid_perf_bench.dart for repeatable frame-timing and CPU profile runs in profile mode.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Описание изменений
Профиль по функциям (см. комментарий в #972) показал: правка одной ячейки пересобирала все видимые строки (~67% времени кадра), а внутри них ~25% уходило на inherited-lookups в каждой ячейке. Поэтому правки убирают саму пересборку неизменившегося, а не удешевляют ячейку.
VirtualResultGridхранит последний_DataRowдля каждой видимой строки и возвращает фреймворку тот же экземпляр, если новая сборка дала бы такую же строку (_DataRow.sameAs). Для==уWidgetнельзя (он@nonVirtual), поэтому повторное использование идёт по экземпляру.Element.updateChildпропускает идентичный виджет._DataRowсталStatefulWidgetи так же хранит_GridCellпо колонкам (ячейки с ключомValueKey(column)), поэтому при сдвиге окна колонок уже построенные ячейки не пересобираются.DataGridStagingBuffer.rowRenderSignature(row): отпечаток статуса строки и изменённых ячеек, нужен, чтобы сравнение видело staged-изменения (буфер одна и та же изменяемая ссылка).columnOverscan2 → 6). Пересборка теперь раз в несколько колонок, а не на каждой.benchmark/grid_perf_bench.dart(MODE=scroll|edit,PROFILE=trueпечатает профиль по функциям).Замеры (profile, Impeller GLES, AMD iGPU, 120 Гц, окно 4096×2576, 5000×120)
Критерии из #972 по build выполнены. Растр не менялся и теперь ограничивает: около 6–7 мс p50 и 9–16 мс p90 на таком окне, то есть часть кадров при панорамировании всё ещё не укладывается в 8,33 мс по растру. Это отдельная работа (меньше draw-операций на ячейку).
Тесты
result_grid_sorting_model_test: правка одной ячейки пересобирает только свою строку, смена выделения затрагивает только старую и новую строки, staged-статус по-прежнему перерисовывает строку, ячейки внутри окна переиспользуются при скролле.data_grid_staging_buffer_test:rowRenderSignatureменяется только вместе со staged-состоянием своей строки.test/features/workspace(253 теста) прогнал локально, все проходят.Не входит
Связанные Issue
Closes #972