Skip to content

Hot-Loop performance improvements in data/grid - #4600

Open
lbwexler wants to merge 1 commit into
developfrom
hot-loop-perf
Open

Hot-Loop performance improvements in data/grid#4600
lbwexler wants to merge 1 commit into
developfrom
hot-loop-perf

Conversation

@lbwexler

@lbwexler lbwexler commented Aug 21, 2026

Copy link
Copy Markdown
Member

Targeted allocation and complexity fixes on per-comparison, per-cell, and per-record hot paths, found in a follow-up perf audit after the v87 wave.

  • Sort path: Column comparators resolve their GridSorter via a new allocation-free GridModel.getSorter() instead of a lodash {colId} matcher per comparison (which allocated matcher internals on every call - ~15M objects for one 400k-row sort). The default path resolves once and passes it into defaultComparator; app comparators calling via params get the cheap lookup automatically.
  • Value reads: new Column.buildFastValueGetter() - when a column uses the default getValueFn, the ag-Grid valueGetter reads record.data directly, skipping the per-call params object (paid per cell render and twice per sort comparison). Custom getValueFns keep the fully-featured path.
  • Tree-grid transactions: Grid now skips its post-transaction expand-state sync - an ag-Grid walk over all rows plus deep-equal/freeze of the state tree - for updates that change no parentId. Adds/removes and grouped-by-value grids sync exactly as before.
  • FieldFilter: =/!=/includes/excludes test via a Set instead of a linear candidate scan per record, capping the O(records × candidates) worst case (e.g. header-filter value selections on high-cardinality columns). =/!= use the Set only when all candidates are primitives, preserving isEqual semantics for Dates; includes/excludes were already SameValueZero, so the Set is semantically exact.

Validated in Toolbox: header sorts incl. abs-value cycling, tree grid reload with expansion preserved, grouped rows, and column filtering (= and tags includes) all clean.

Stacked follow-up with a second batch (StoreValidator, GridFindField, selection sync): #4602.

* Column comparators resolve their GridSorter via new allocation-free GridModel.getSorter() instead of a lodash matcher per comparison; the default path resolves once and passes it into defaultComparator. Eliminates ~15M transient allocations on a 400k-row sort.
* Column.buildFastValueGetter(): the default ag-Grid valueGetter now reads record data directly, skipping the per-call params object (built per cell render and twice per sort comparison).
* Grid skips its post-transaction expand-state sync (an ag-Grid walk over all rows) for tree-grid updates that change no parentId. Grouped-by-value grids retain existing always-sync behavior.
* FieldFilter =/!=/includes/excludes test with a Set-based lookup instead of a linear scan per record, capping the O(records x candidates) worst case from large header-filter value selections. =/!= use the Set only for all-primitive candidates, preserving isEqual semantics for Dates; includes/excludes were already SameValueZero, so the Set is an exact match.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant