Skip to content

feat: improve sortFns, filterFns, aggregationFns performance more#6371

Merged
KevinVandy merged 2 commits into
betafrom
perf-fns
Jul 3, 2026
Merged

feat: improve sortFns, filterFns, aggregationFns performance more#6371
KevinVandy merged 2 commits into
betafrom
perf-fns

Conversation

@KevinVandy

@KevinVandy KevinVandy commented Jul 3, 2026

Copy link
Copy Markdown
Member

🎯 Changes

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm test:pr.

Summary by CodeRabbit

  • New Features

    • Added an Email column to the sorting examples across frameworks, with alphanumeric sorting enabled.
    • Example data generation now includes generated email values so the new column is populated in the demos.
  • Bug Fixes

    • Improved sorting consistency, including more reliable datetime, alphanumeric, and multi-column sort behavior (including handling of undefined values).
    • Improved filtering behavior, including correct auto-filter selection for arrays, refined numeric/string/range filtering semantics, and more robust array-filter matching.

@nx-cloud

nx-cloud Bot commented Jul 3, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 9df72cc

Command Status Duration Result
nx affected --targets=test:eslint,test:sherif,t... ✅ Succeeded 6m 17s View ↗
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 44s View ↗

☁️ Nx Cloud last updated this comment at 2026-07-03 05:08:05 UTC

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1b0f0d30-5c47-48db-8b2e-f085e8763150

📥 Commits

Reviewing files that changed from the base of the PR and between fe0fe4f and 9df72cc.

📒 Files selected for processing (5)
  • packages/table-core/src/features/row-sorting/createSortedRowModel.ts
  • packages/table-core/src/fns/filterFns.ts
  • packages/table-core/tests/unit/core/table/rowModelSlots.test.ts
  • packages/table-core/tests/unit/fns/filterFns.test.ts
  • perf-done.md
✅ Files skipped from review due to trivial changes (1)
  • perf-done.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/table-core/tests/unit/fns/filterFns.test.ts
  • packages/table-core/tests/unit/core/table/rowModelSlots.test.ts
  • packages/table-core/src/fns/filterFns.ts

📝 Walkthrough

Walkthrough

Adds email columns and faker-generated email values across the sorting examples, and refactors table-core sorting, filtering, aggregation, and sort functions with matching tests and perf catalog updates.

Changes

Sorting Examples: Email Column

Layer / File(s) Summary
Add email column and generator across all sorting examples
examples/{alpine,angular,lit,preact,react,solid,svelte,vanilla,vue}/sorting/src/*
Each example adds an email column with alphanumeric sorting and updates Person/makeData to generate an email from firstName/lastName via faker, with @ randomization and lowercasing.

Table-Core Performance Refactors

Layer / File(s) Summary
Auto-filter array/object type check fix
packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts, packages/table-core/tests/unit/features/column-filtering/columnFilteringFeature.utils.test.ts
Reorders array vs object checks so arrays consistently use arrIncludes, and adds unit tests for array and object auto-filter selection.
Sorted row model comparator refactor
packages/table-core/src/features/row-sorting/createSortedRowModel.ts, packages/table-core/tests/unit/core/table/rowModelSlots.test.ts
Replaces columnInfoById lookup logic with a resolvedSorting array and compareRows function, and adds a multi-sort ordering test.
Aggregation function loop refactor
packages/table-core/src/fns/aggregationFns.ts, packages/table-core/tests/unit/fns/aggregationFns.test.ts
Converts sum/min/max/extent/mean from reduce/forEach to indexed loops and adds unit tests for numeric, NaN, and non-numeric handling.
Filter function metadata and loop rewrites
packages/table-core/src/fns/filterFns.ts, packages/table-core/tests/unit/fns/filterFns.test.ts
Adds resolveFilterValue to string filters, switches numeric filters to autoRemove, rewrites between/betweenInclusive and array filters as explicit loops, and adds matching tests.
Datetime and alphanumeric sort rewrite
packages/table-core/src/fns/sortFns.ts, packages/table-core/tests/unit/fns/sortFns.test.ts
Adds toDateSortValue normalization and replaces regex-based compareAlphanumeric with chunk-scanning comparison, with expanded tests.
Perf catalog documentation
perf-done.md, perf-skipped.md, perf-todo.md
Updates catalog counts and entries documenting completed, skipped, and remaining performance findings tied to the refactors.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • TanStack/table#6310: Both PRs modify the compareAlphanumeric logic in packages/table-core/src/fns/sortFns.ts.
  • TanStack/table#6332: Both PRs modify filterFn_between / filterFn_betweenInclusive in packages/table-core/src/fns/filterFns.ts.
  • TanStack/table#6338: Both PRs modify sorting logic in packages/table-core/src/features/row-sorting/createSortedRowModel.ts, including makeObjectMap usage.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change set: performance-focused updates to sortFns, filterFns, and aggregationFns.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf-fns

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Jul 3, 2026

Copy link
Copy Markdown
More templates

@tanstack/alpine-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/alpine-table@6371

@tanstack/angular-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/angular-table@6371

@tanstack/angular-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/angular-table-devtools@6371

@tanstack/lit-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/lit-table@6371

@tanstack/match-sorter-utils

npm i https://pkg.pr.new/TanStack/table/@tanstack/match-sorter-utils@6371

@tanstack/preact-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/preact-table@6371

@tanstack/preact-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/preact-table-devtools@6371

@tanstack/react-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/react-table@6371

@tanstack/react-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/react-table-devtools@6371

@tanstack/solid-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/solid-table@6371

@tanstack/solid-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/solid-table-devtools@6371

@tanstack/svelte-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/svelte-table@6371

@tanstack/table-core

npm i https://pkg.pr.new/TanStack/table/@tanstack/table-core@6371

@tanstack/table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/table-devtools@6371

@tanstack/vue-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/vue-table@6371

@tanstack/vue-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/vue-table-devtools@6371

commit: 9df72cc

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (3)
examples/lit/sorting/src/makeData.ts (1)

25-34: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Email is generated from lastName even when the row's lastName is set to undefined.

Since email uses the local lastName variable directly (line 32) regardless of the coin-flip that nulls out the returned lastName field (line 30), rows with an undefined last name will still show a last-name-derived email. This is a demo data quirk, not a functional bug, but slightly inconsistent for anyone inspecting the data.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/lit/sorting/src/makeData.ts` around lines 25 - 34, The generated
email in makeData currently uses the local lastName value even when the returned
object omits lastName, so the demo data can look inconsistent. Update makeData
so the email is derived from the same effective lastName that is returned in the
object, or fall back to a non-last-name-based value when lastName is undefined;
keep the logic localized around makeData and its email construction.
perf-done.md (1)

1601-1666: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Doc claims "Risk: None" but misses an edge case found in review.

The catalog entry states this rewrite is a "pure strength reduction" with semantics "preserved verbatim," but the reviewed source (filterFns.ts:224-242,259-277) has a latent bug where Number('') coerces to 0 rather than NaN, causing blank-min + negative-max combinations to bypass the max bound. Worth updating this note once the source fix lands.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@perf-done.md` around lines 1601 - 1666, Update the `filterFn_between` /
`filterFn_betweenInclusive` performance note in `perf-done.md` to remove the
blanket “Risk: None” / “semantics preserved verbatim” claim and add the reviewed
edge case about `Number('')` coercing to `0`, which can let blank-min plus
negative-max cases bypass the max bound. Keep the entry aligned with the actual
`filterFns.ts` behavior and mention that the note should be revised once the
source fix for `filterFn_between` and `filterFn_betweenInclusive` is in place.
packages/table-core/tests/unit/fns/filterFns.test.ts (1)

570-626: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider adding a blank-min + negative-max case.

These new between/betweenInclusive tests cover strict/inclusive/open-ended/reversed cases well, but none pair a blank endpoint (''/undefined) with a negative number on the other side — the exact combination that trips the Number('') === 0 issue flagged in filterFns.ts. Adding such a case would have caught that regression.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/table-core/tests/unit/fns/filterFns.test.ts` around lines 570 - 626,
Add a regression test for filterFns.between and/or filterFns.betweenInclusive
that uses a blank endpoint ('' or undefined) paired with a negative bound, since
the current cases in filterFns.test only cover positive values. Update the
describe blocks for filterFns.between and filterFns.betweenInclusive to include
this blank-min/negative-max scenario and assert the expected open-ended behavior
so the Number('') coercion issue is caught.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/table-core/src/features/row-sorting/createSortedRowModel.ts`:
- Around line 104-106: The comparator in createSortedRowModel should treat the
“both undefined” case as a tie before applying sortUndefined handling. Update
the undefined-check branch so that when both aUndefined and bUndefined are true
it returns 0 and allows later multi-sort keys to resolve the order, while
keeping the existing first/last behavior only for the single-undefined case. Use
the aUndefined, bUndefined, and sortUndefined logic in the sorting comparator to
locate the fix.

In `@packages/table-core/src/fns/filterFns.ts`:
- Around line 224-242: The upper-bound check in the range filter logic is
incorrectly treating a blank minimum as numeric zero, which lets rows pass when
max is negative. Update the range validation in filterFns.ts within the function
handling the min/max comparison so blank endpoints are excluded before computing
numericMin/numericMax or doing the reversed-range check. Apply the same fix in
filterFn_betweenInclusive so both range filters consistently ignore empty bounds
and still enforce the upper limit.
- Around line 359-365: The arrIncludes filter path in filterFns.ts can throw
when row values are nullish, so update filterFn_arrIncludes to guard the row
value before calling includes. Reuse the same null/Array.isArray-style check
already used by the sibling helpers in this module, and keep the behavior
aligned with column_getAutoFilterFn’s arrIncludes selection for array columns.

In `@packages/table-core/tests/unit/core/table/rowModelSlots.test.ts`:
- Around line 164-166: The sort assertion in rowModelSlots.test.ts should
reflect the tie-break behavior for rows with undefined priority. Update the
expectation for table.getSortedRowModel().rows.map(...) so the rows with tied
primary sort key use the secondary inverted score ordering, with the relevant
check around the table sorting setup and row.original.name results.

---

Nitpick comments:
In `@examples/lit/sorting/src/makeData.ts`:
- Around line 25-34: The generated email in makeData currently uses the local
lastName value even when the returned object omits lastName, so the demo data
can look inconsistent. Update makeData so the email is derived from the same
effective lastName that is returned in the object, or fall back to a
non-last-name-based value when lastName is undefined; keep the logic localized
around makeData and its email construction.

In `@packages/table-core/tests/unit/fns/filterFns.test.ts`:
- Around line 570-626: Add a regression test for filterFns.between and/or
filterFns.betweenInclusive that uses a blank endpoint ('' or undefined) paired
with a negative bound, since the current cases in filterFns.test only cover
positive values. Update the describe blocks for filterFns.between and
filterFns.betweenInclusive to include this blank-min/negative-max scenario and
assert the expected open-ended behavior so the Number('') coercion issue is
caught.

In `@perf-done.md`:
- Around line 1601-1666: Update the `filterFn_between` /
`filterFn_betweenInclusive` performance note in `perf-done.md` to remove the
blanket “Risk: None” / “semantics preserved verbatim” claim and add the reviewed
edge case about `Number('')` coercing to `0`, which can let blank-min plus
negative-max cases bypass the max bound. Keep the entry aligned with the actual
`filterFns.ts` behavior and mention that the note should be revised once the
source fix for `filterFn_between` and `filterFn_betweenInclusive` is in place.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 93ea5b37-a160-4a3b-b340-1e35aa42e786

📥 Commits

Reviewing files that changed from the base of the PR and between 20868e5 and fe0fe4f.

📒 Files selected for processing (31)
  • examples/alpine/sorting/src/main.ts
  • examples/alpine/sorting/src/makeData.ts
  • examples/angular/sorting/src/app/app.ts
  • examples/angular/sorting/src/app/makeData.ts
  • examples/lit/sorting/src/main.ts
  • examples/lit/sorting/src/makeData.ts
  • examples/preact/sorting/src/main.tsx
  • examples/preact/sorting/src/makeData.ts
  • examples/react/sorting/src/main.tsx
  • examples/react/sorting/src/makeData.ts
  • examples/solid/sorting/src/App.tsx
  • examples/solid/sorting/src/makeData.ts
  • examples/svelte/sorting/src/App.svelte
  • examples/svelte/sorting/src/makeData.ts
  • examples/vanilla/sorting/src/main.ts
  • examples/vanilla/sorting/src/makeData.ts
  • examples/vue/sorting/src/App.vue
  • examples/vue/sorting/src/makeData.ts
  • packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts
  • packages/table-core/src/features/row-sorting/createSortedRowModel.ts
  • packages/table-core/src/fns/aggregationFns.ts
  • packages/table-core/src/fns/filterFns.ts
  • packages/table-core/src/fns/sortFns.ts
  • packages/table-core/tests/unit/core/table/rowModelSlots.test.ts
  • packages/table-core/tests/unit/features/column-filtering/columnFilteringFeature.utils.test.ts
  • packages/table-core/tests/unit/fns/aggregationFns.test.ts
  • packages/table-core/tests/unit/fns/filterFns.test.ts
  • packages/table-core/tests/unit/fns/sortFns.test.ts
  • perf-done.md
  • perf-skipped.md
  • perf-todo.md

Comment thread packages/table-core/src/fns/filterFns.ts
Comment thread packages/table-core/src/fns/filterFns.ts Outdated
Comment thread packages/table-core/tests/unit/core/table/rowModelSlots.test.ts Outdated
@KevinVandy KevinVandy merged commit 5480a6f into beta Jul 3, 2026
8 checks passed
@KevinVandy KevinVandy deleted the perf-fns branch July 3, 2026 05:09
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