Skip to content

Commit d60cf84

Browse files
committed
Try speeding up entity adapter by minimizing Immer reads
1 parent bece99b commit d60cf84

File tree

2 files changed

+53
-16
lines changed

2 files changed

+53
-16
lines changed

packages/toolkit/src/entities/sorted_state_adapter.ts

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
selectIdValue,
1414
ensureEntitiesArray,
1515
splitAddedUpdatedEntities,
16+
getCurrent,
1617
} from './utils'
1718

1819
export function findInsertIndex<T>(
@@ -65,11 +66,17 @@ export function createSortedStateAdapter<T, Id extends EntityId>(
6566
function addManyMutably(
6667
newEntities: readonly T[] | Record<Id, T>,
6768
state: R,
69+
existingIds?: Id[],
6870
): void {
6971
newEntities = ensureEntitiesArray(newEntities)
7072

73+
const existingKeys = new Set<Id>(
74+
existingIds ?? (current(state.ids) as Id[]),
75+
)
76+
7177
const models = newEntities.filter(
72-
(model) => !(selectIdValue(model, selectId) in state.entities),
78+
// (model) => !(selectId(model) in state.entities),
79+
(model) => !existingKeys.has(selectIdValue(model, selectId)),
7380
)
7481

7582
if (models.length !== 0) {
@@ -103,7 +110,7 @@ export function createSortedStateAdapter<T, Id extends EntityId>(
103110
state.entities = {} as Record<Id, T>
104111
state.ids = []
105112

106-
addManyMutably(newEntities, state)
113+
addManyMutably(newEntities, state, [])
107114
}
108115

109116
function updateOneMutably(update: Update<T, Id>, state: R): void {
@@ -153,14 +160,18 @@ export function createSortedStateAdapter<T, Id extends EntityId>(
153160
newEntities: readonly T[] | Record<Id, T>,
154161
state: R,
155162
): void {
156-
const [added, updated] = splitAddedUpdatedEntities<T, Id>(
163+
const [added, updated, existingIdsArray] = splitAddedUpdatedEntities<T, Id>(
157164
newEntities,
158165
selectId,
159166
state,
160167
)
161168

162-
updateManyMutably(updated, state)
163-
addManyMutably(added, state)
169+
if (updated.length) {
170+
updateManyMutably(updated, state)
171+
}
172+
if (added.length) {
173+
addManyMutably(added, state, existingIdsArray)
174+
}
164175
}
165176

166177
function areArraysEqual(a: readonly unknown[], b: readonly unknown[]) {
@@ -311,10 +322,14 @@ export function createSortedStateAdapter<T, Id extends EntityId>(
311322
updatedIds,
312323
replacedIds,
313324
) => {
314-
const entities = state.entities as Record<Id, T>
315-
let ids = state.ids as Id[]
325+
const currentEntities = getCurrent(state.entities) as Record<Id, T>
326+
const currentIds = getCurrent(state.ids) as Id[]
327+
// const entities = state.entities as Record<Id, T>
328+
const stateEntities = state.entities as Record<Id, T>
329+
// let ids = state.ids as Id[]
330+
let ids = currentIds
316331
if (replacedIds) {
317-
ids = Array.from(new Set(ids))
332+
ids = Array.from(new Set(currentIds))
318333
}
319334

320335
// //let sortedEntities: T[] = []
@@ -335,9 +350,16 @@ export function createSortedStateAdapter<T, Id extends EntityId>(
335350
// }
336351
// }
337352
// }
338-
let sortedEntities = ids // Array.from(new Set(state.ids as Id[]))
339-
.map((id) => entities[id])
340-
.filter(Boolean)
353+
let sortedEntities: T[] = []
354+
for (const id of ids) {
355+
const entity = currentEntities[id]
356+
if (entity) {
357+
sortedEntities.push(entity)
358+
}
359+
}
360+
// let sortedEntities = ids // Array.from(new Set(state.ids as Id[]))
361+
// .map((id) => currentEntities[id])
362+
// .filter(Boolean)
341363

342364
const wasPreviouslyEmpty = sortedEntities.length === 0
343365

@@ -356,7 +378,7 @@ export function createSortedStateAdapter<T, Id extends EntityId>(
356378

357379
// Insert/overwrite all new/updated
358380
for (const item of addedItems) {
359-
entities[selectId(item)] = item
381+
stateEntities[selectId(item)] = item
360382
// console.log('Inserting: ', isDraft(item) ? current(item) : item)
361383
if (!wasPreviouslyEmpty) {
362384
insert(sortedEntities, item, comparer)
@@ -366,12 +388,18 @@ export function createSortedStateAdapter<T, Id extends EntityId>(
366388
if (wasPreviouslyEmpty) {
367389
sortedEntities = addedItems.slice().sort(comparer)
368390
} else if (updatedIds?.size) {
391+
for (const updatedId of updatedIds) {
392+
const item: T = currentEntities[updatedId]
393+
// const currentIndex = sortedEntities.indexOf(item)
394+
// const newIndex = findInsertIndex(sortedEntities, item, comparer)
395+
// console.log('Item: ', updatedId, { currentIndex, newIndex })
396+
}
369397
sortedEntities.sort(comparer)
370398
}
371399

372400
const newSortedIds = sortedEntities.map(selectId)
373401
// console.log('New sorted IDs: ', newSortedIds)
374-
if (!areArraysEqual(state.ids, newSortedIds)) {
402+
if (!areArraysEqual(currentIds, newSortedIds)) {
375403
state.ids = newSortedIds
376404
}
377405
}

packages/toolkit/src/entities/utils.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { current, isDraft } from 'immer'
12
import type {
23
IdSelector,
34
Update,
@@ -35,23 +36,31 @@ export function ensureEntitiesArray<T, Id extends EntityId>(
3536
return entities
3637
}
3738

39+
export function getCurrent<T>(value: T): T {
40+
return isDraft(value) ? current(value) : value
41+
}
42+
3843
export function splitAddedUpdatedEntities<T, Id extends EntityId>(
3944
newEntities: readonly T[] | Record<Id, T>,
4045
selectId: IdSelector<T, Id>,
4146
state: DraftableEntityState<T, Id>,
42-
): [T[], Update<T, Id>[]] {
47+
): [T[], Update<T, Id>[], Id[]] {
4348
newEntities = ensureEntitiesArray(newEntities)
4449

50+
const existingIdsArray = current(state.ids) as Id[]
51+
const existingIds = new Set<Id>(existingIdsArray)
52+
4553
const added: T[] = []
4654
const updated: Update<T, Id>[] = []
4755

4856
for (const entity of newEntities) {
4957
const id = selectIdValue(entity, selectId)
50-
if (id in state.entities) {
58+
if (existingIds.has(id)) {
59+
// if (id in state.entities) {
5160
updated.push({ id, changes: entity })
5261
} else {
5362
added.push(entity)
5463
}
5564
}
56-
return [added, updated]
65+
return [added, updated, existingIdsArray]
5766
}

0 commit comments

Comments
 (0)