Skip to content

Commit 70196a4

Browse files
authored
perf(reactivity): optimize array tracking (#9511)
close #4318
1 parent 72bde94 commit 70196a4

File tree

7 files changed

+849
-120
lines changed

7 files changed

+849
-120
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,86 @@
11
import { bench } from 'vitest'
2-
import { computed, reactive, readonly, shallowRef, triggerRef } from '../src'
2+
import { effect, reactive, shallowReadArray } from '../src'
33

44
for (let amount = 1e1; amount < 1e4; amount *= 10) {
55
{
6-
const rawArray: any[] = []
6+
const rawArray: number[] = []
77
for (let i = 0, n = amount; i < n; i++) {
88
rawArray.push(i)
99
}
10-
const r = reactive(rawArray)
11-
const c = computed(() => {
12-
return r.reduce((v, a) => a + v, 0)
10+
const arr = reactive(rawArray)
11+
12+
bench(`track for loop, ${amount} elements`, () => {
13+
let sum = 0
14+
effect(() => {
15+
for (let i = 0; i < arr.length; i++) {
16+
sum += arr[i]
17+
}
18+
})
1319
})
20+
}
1421

15-
bench(`reduce *reactive* array, ${amount} elements`, () => {
16-
for (let i = 0, n = r.length; i < n; i++) {
17-
r[i]++
18-
}
19-
c.value
22+
{
23+
const rawArray: number[] = []
24+
for (let i = 0, n = amount; i < n; i++) {
25+
rawArray.push(i)
26+
}
27+
const arr = reactive(rawArray)
28+
29+
bench(`track manual reactiveReadArray, ${amount} elements`, () => {
30+
let sum = 0
31+
effect(() => {
32+
const raw = shallowReadArray(arr)
33+
for (let i = 0; i < raw.length; i++) {
34+
sum += raw[i]
35+
}
36+
})
37+
})
38+
}
39+
40+
{
41+
const rawArray: number[] = []
42+
for (let i = 0, n = amount; i < n; i++) {
43+
rawArray.push(i)
44+
}
45+
const arr = reactive(rawArray)
46+
47+
bench(`track iteration, ${amount} elements`, () => {
48+
let sum = 0
49+
effect(() => {
50+
for (let x of arr) {
51+
sum += x
52+
}
53+
})
54+
})
55+
}
56+
57+
{
58+
const rawArray: number[] = []
59+
for (let i = 0, n = amount; i < n; i++) {
60+
rawArray.push(i)
61+
}
62+
const arr = reactive(rawArray)
63+
64+
bench(`track forEach, ${amount} elements`, () => {
65+
let sum = 0
66+
effect(() => {
67+
arr.forEach(x => (sum += x))
68+
})
69+
})
70+
}
71+
72+
{
73+
const rawArray: number[] = []
74+
for (let i = 0, n = amount; i < n; i++) {
75+
rawArray.push(i)
76+
}
77+
const arr = reactive(rawArray)
78+
79+
bench(`track reduce, ${amount} elements`, () => {
80+
let sum = 0
81+
effect(() => {
82+
sum = arr.reduce((v, a) => a + v, 0)
83+
})
2084
})
2185
}
2286

@@ -26,15 +90,12 @@ for (let amount = 1e1; amount < 1e4; amount *= 10) {
2690
rawArray.push(i)
2791
}
2892
const r = reactive(rawArray)
29-
const c = computed(() => {
30-
return r.reduce((v, a) => a + v, 0)
31-
})
93+
effect(() => r.reduce((v, a) => a + v, 0))
3294

3395
bench(
34-
`reduce *reactive* array, ${amount} elements, only change first value`,
96+
`trigger index mutation (1st only), tracked with reduce, ${amount} elements`,
3597
() => {
3698
r[0]++
37-
c.value
3899
},
39100
)
40101
}
@@ -44,30 +105,34 @@ for (let amount = 1e1; amount < 1e4; amount *= 10) {
44105
for (let i = 0, n = amount; i < n; i++) {
45106
rawArray.push(i)
46107
}
47-
const r = reactive({ arr: readonly(rawArray) })
48-
const c = computed(() => {
49-
return r.arr.reduce((v, a) => a + v, 0)
50-
})
108+
const r = reactive(rawArray)
109+
effect(() => r.reduce((v, a) => a + v, 0))
51110

52-
bench(`reduce *readonly* array, ${amount} elements`, () => {
53-
r.arr = r.arr.map(v => v + 1)
54-
c.value
55-
})
111+
bench(
112+
`trigger index mutation (all), tracked with reduce, ${amount} elements`,
113+
() => {
114+
for (let i = 0, n = r.length; i < n; i++) {
115+
r[i]++
116+
}
117+
},
118+
)
56119
}
57120

58121
{
59-
const rawArray: any[] = []
122+
const rawArray: number[] = []
60123
for (let i = 0, n = amount; i < n; i++) {
61124
rawArray.push(i)
62125
}
63-
const r = shallowRef(rawArray)
64-
const c = computed(() => {
65-
return r.value.reduce((v, a) => a + v, 0)
126+
const arr = reactive(rawArray)
127+
let sum = 0
128+
effect(() => {
129+
for (let x of arr) {
130+
sum += x
131+
}
66132
})
67133

68-
bench(`reduce *raw* array, copied, ${amount} elements`, () => {
69-
r.value = r.value.map(v => v + 1)
70-
c.value
134+
bench(`push() trigger, tracked via iteration, ${amount} elements`, () => {
135+
arr.push(1)
71136
})
72137
}
73138

@@ -76,17 +141,14 @@ for (let amount = 1e1; amount < 1e4; amount *= 10) {
76141
for (let i = 0, n = amount; i < n; i++) {
77142
rawArray.push(i)
78143
}
79-
const r = shallowRef(rawArray)
80-
const c = computed(() => {
81-
return r.value.reduce((v, a) => a + v, 0)
144+
const arr = reactive(rawArray)
145+
let sum = 0
146+
effect(() => {
147+
arr.forEach(x => (sum += x))
82148
})
83149

84-
bench(`reduce *raw* array, manually triggered, ${amount} elements`, () => {
85-
for (let i = 0, n = rawArray.length; i < n; i++) {
86-
rawArray[i]++
87-
}
88-
triggerRef(r)
89-
c.value
150+
bench(`push() trigger, tracked via forEach, ${amount} elements`, () => {
151+
arr.push(1)
90152
})
91153
}
92154
}

0 commit comments

Comments
 (0)