Skip to content

Commit e2a87db

Browse files
committed
Add RTKQ large object perf testing script
1 parent 78ecf74 commit e2a87db

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

perf-testing/rtkq-testing.mjs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import {produce} from "../dist/immer.mjs"
2+
3+
function createInitialState(arraySize = BENCHMARK_CONFIG.arraySize) {
4+
const initialState = {
5+
largeArray: Array.from({length: arraySize}, (_, i) => ({
6+
id: i,
7+
value: Math.random(),
8+
nested: {key: `key-${i}`, data: Math.random()},
9+
moreNested: {
10+
items: Array.from(
11+
{length: BENCHMARK_CONFIG.nestedArraySize},
12+
(_, i) => ({id: i, name: String(i)})
13+
)
14+
}
15+
})),
16+
otherData: Array.from({length: arraySize}, (_, i) => ({
17+
id: i,
18+
name: `name-${i}`,
19+
isActive: i % 2 === 0
20+
})),
21+
api: {
22+
queries: {},
23+
provided: {
24+
keys: {}
25+
},
26+
subscriptions: {}
27+
}
28+
}
29+
return initialState
30+
}
31+
32+
const MAX = 1
33+
34+
const BENCHMARK_CONFIG = {
35+
iterations: 1,
36+
arraySize: 100,
37+
nestedArraySize: 10,
38+
multiUpdateCount: 5,
39+
reuseStateIterations: 10
40+
}
41+
42+
// RTKQ-style action creators
43+
const rtkqPending = index => ({
44+
type: "rtkq/pending",
45+
payload: {
46+
cacheKey: `some("test-${index}-")`,
47+
requestId: `req-${index}`,
48+
id: `test-${index}-`
49+
}
50+
})
51+
52+
const rtkqResolved = index => ({
53+
type: "rtkq/resolved",
54+
payload: {
55+
cacheKey: `some("test-${index}-")`,
56+
requestId: `req-${index}`,
57+
id: `test-${index}-`,
58+
data: `test-${index}-1`
59+
}
60+
})
61+
62+
const createImmerReducer = produce => {
63+
const immerReducer = (state = createInitialState(), action) =>
64+
produce(state, draft => {
65+
switch (action.type) {
66+
case "rtkq/pending": {
67+
// Simulate separate RTK slice reducers with combined reducer pattern
68+
const cacheKey = action.payload.cacheKey
69+
draft.api.queries[cacheKey] = {
70+
id: action.payload.id,
71+
status: "pending",
72+
data: undefined
73+
}
74+
draft.api.provided.keys[cacheKey] = {}
75+
draft.api.subscriptions[cacheKey] = {
76+
[action.payload.requestId]: {
77+
pollingInterval: 0,
78+
skipPollingIfUnfocused: false
79+
}
80+
}
81+
break
82+
}
83+
case "rtkq/resolved": {
84+
const cacheKey = action.payload.cacheKey
85+
draft.api.queries[cacheKey].status = "fulfilled"
86+
draft.api.queries[cacheKey].data = action.payload.data
87+
// provided and subscriptions don't change on resolved
88+
break
89+
}
90+
}
91+
})
92+
93+
return immerReducer
94+
}
95+
96+
const immerReducer = createImmerReducer(produce)
97+
const initialState = createInitialState()
98+
99+
const arraySizes = [10, 100, 250, 500, 1000, 1021, 1500, 2000, 3000]
100+
101+
for (const arraySize of arraySizes) {
102+
console.log(`Running benchmark with array size: ${arraySize}`)
103+
104+
const start = performance.now()
105+
106+
let state = initialState
107+
108+
// Phase 1: Execute all pending actions
109+
for (let i = 0; i < arraySize; i++) {
110+
state = immerReducer(state, rtkqPending(i))
111+
}
112+
113+
// Phase 2: Execute all resolved actions
114+
for (let i = 0; i < arraySize; i++) {
115+
state = immerReducer(state, rtkqResolved(i))
116+
}
117+
118+
const end = performance.now()
119+
const total = end - start
120+
const avg = total / arraySize
121+
122+
console.log(
123+
`Done in ${total.toFixed(1)} ms (items: ${arraySize}, avg: ${avg.toFixed(
124+
3
125+
)} ms / item)`
126+
)
127+
}

0 commit comments

Comments
 (0)