Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Improve grouping performance (#4495)
* When grouping data that has large clusters of values, generating grouped columns becomes extremely slow. For instance: 50k rows, 3 grouped columns, each grouped column has an identical value (so each groups together 50k rows each) - takes ~30 seconds * The performance bottleneck is `[...previous, row]` - it has to recreate the previous array over and over again, getting slower and slower each time. Using `.push` instead takes it from 30 seconds down to < 100ms to generate the groupings (overall table generation goes down to < 1 second). * `push` is safe in this case because all of the data is constructed in the `groupBy` method so we are not mutating data from anywhere that would require generating new arrays using spread every iteration
- Loading branch information
Showing
4 changed files
with
51 additions
and
4 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
import faker from 'faker' | ||
import faker from '@faker-js/faker' | ||
|
||
export type Person = { | ||
firstName: string | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { ColumnDef, getCoreRowModel } from '../src'; | ||
import { createColumnHelper } from '../src/columnHelper'; | ||
import { createTable } from '../src/core/table'; | ||
import { getGroupedRowModel } from '../src/utils/getGroupedRowModel'; | ||
import { makeData, Person } from './makeTestData'; | ||
|
||
type personKeys = keyof Person; | ||
type PersonColumn = ColumnDef<Person, string | number | Person[] | undefined>; | ||
|
||
function generateColumns(people: Person[]): PersonColumn[] { | ||
const columnHelper = createColumnHelper<Person>(); | ||
const person = people[0]; | ||
return Object.keys(person).map((key) => { | ||
const typedKey = key as personKeys; | ||
return columnHelper.accessor(typedKey, { id: typedKey }); | ||
}); | ||
} | ||
|
||
describe('#getGroupedRowModel', () => { | ||
it('groups 50k rows and 3 grouped columns with clustered data in less than 2 seconds', () => { | ||
const data = makeData(50000); | ||
const columns = generateColumns(data); | ||
const grouping = ['firstName', 'lastName', 'age']; | ||
const start = new Date(); | ||
|
||
data.forEach((p) => p.firstName = 'Fixed') | ||
data.forEach((p) => p.lastName = 'Name') | ||
data.forEach((p) => p.age = 123) | ||
|
||
const table = createTable<Person>({ | ||
onStateChange() {}, | ||
renderFallbackValue: '', | ||
data, | ||
state: { grouping }, | ||
columns, | ||
getCoreRowModel: getCoreRowModel(), | ||
getGroupedRowModel: getGroupedRowModel() | ||
}) | ||
const groupedById = table.getGroupedRowModel().rowsById; | ||
const end = new Date(); | ||
|
||
expect(groupedById['firstName:Fixed'].leafRows.length).toEqual(50000) | ||
expect(groupedById['firstName:Fixed>lastName:Name'].leafRows.length).toEqual(50000) | ||
expect(groupedById['firstName:Fixed>lastName:Name>age:123'].leafRows.length).toEqual(50000) | ||
expect(end.valueOf() - start.valueOf()).toBeLessThan(2000); | ||
}); | ||
}) |
This file contains 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
This file contains 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