Skip to content

Commit

Permalink
perf(reactivity): optimize array tracking (#9511)
Browse files Browse the repository at this point in the history
close #4318
  • Loading branch information
jods4 authored Feb 26, 2024
1 parent 72bde94 commit 70196a4
Show file tree
Hide file tree
Showing 7 changed files with 849 additions and 120 deletions.
140 changes: 101 additions & 39 deletions packages/reactivity/__benchmarks__/reactiveArray.bench.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,86 @@
import { bench } from 'vitest'
import { computed, reactive, readonly, shallowRef, triggerRef } from '../src'
import { effect, reactive, shallowReadArray } from '../src'

for (let amount = 1e1; amount < 1e4; amount *= 10) {
{
const rawArray: any[] = []
const rawArray: number[] = []
for (let i = 0, n = amount; i < n; i++) {
rawArray.push(i)
}
const r = reactive(rawArray)
const c = computed(() => {
return r.reduce((v, a) => a + v, 0)
const arr = reactive(rawArray)

bench(`track for loop, ${amount} elements`, () => {
let sum = 0
effect(() => {
for (let i = 0; i < arr.length; i++) {
sum += arr[i]
}
})
})
}

bench(`reduce *reactive* array, ${amount} elements`, () => {
for (let i = 0, n = r.length; i < n; i++) {
r[i]++
}
c.value
{
const rawArray: number[] = []
for (let i = 0, n = amount; i < n; i++) {
rawArray.push(i)
}
const arr = reactive(rawArray)

bench(`track manual reactiveReadArray, ${amount} elements`, () => {
let sum = 0
effect(() => {
const raw = shallowReadArray(arr)
for (let i = 0; i < raw.length; i++) {
sum += raw[i]
}
})
})
}

{
const rawArray: number[] = []
for (let i = 0, n = amount; i < n; i++) {
rawArray.push(i)
}
const arr = reactive(rawArray)

bench(`track iteration, ${amount} elements`, () => {
let sum = 0
effect(() => {
for (let x of arr) {
sum += x
}
})
})
}

{
const rawArray: number[] = []
for (let i = 0, n = amount; i < n; i++) {
rawArray.push(i)
}
const arr = reactive(rawArray)

bench(`track forEach, ${amount} elements`, () => {
let sum = 0
effect(() => {
arr.forEach(x => (sum += x))
})
})
}

{
const rawArray: number[] = []
for (let i = 0, n = amount; i < n; i++) {
rawArray.push(i)
}
const arr = reactive(rawArray)

bench(`track reduce, ${amount} elements`, () => {
let sum = 0
effect(() => {
sum = arr.reduce((v, a) => a + v, 0)
})
})
}

Expand All @@ -26,15 +90,12 @@ for (let amount = 1e1; amount < 1e4; amount *= 10) {
rawArray.push(i)
}
const r = reactive(rawArray)
const c = computed(() => {
return r.reduce((v, a) => a + v, 0)
})
effect(() => r.reduce((v, a) => a + v, 0))

bench(
`reduce *reactive* array, ${amount} elements, only change first value`,
`trigger index mutation (1st only), tracked with reduce, ${amount} elements`,
() => {
r[0]++
c.value
},
)
}
Expand All @@ -44,30 +105,34 @@ for (let amount = 1e1; amount < 1e4; amount *= 10) {
for (let i = 0, n = amount; i < n; i++) {
rawArray.push(i)
}
const r = reactive({ arr: readonly(rawArray) })
const c = computed(() => {
return r.arr.reduce((v, a) => a + v, 0)
})
const r = reactive(rawArray)
effect(() => r.reduce((v, a) => a + v, 0))

bench(`reduce *readonly* array, ${amount} elements`, () => {
r.arr = r.arr.map(v => v + 1)
c.value
})
bench(
`trigger index mutation (all), tracked with reduce, ${amount} elements`,
() => {
for (let i = 0, n = r.length; i < n; i++) {
r[i]++
}
},
)
}

{
const rawArray: any[] = []
const rawArray: number[] = []
for (let i = 0, n = amount; i < n; i++) {
rawArray.push(i)
}
const r = shallowRef(rawArray)
const c = computed(() => {
return r.value.reduce((v, a) => a + v, 0)
const arr = reactive(rawArray)
let sum = 0
effect(() => {
for (let x of arr) {
sum += x
}
})

bench(`reduce *raw* array, copied, ${amount} elements`, () => {
r.value = r.value.map(v => v + 1)
c.value
bench(`push() trigger, tracked via iteration, ${amount} elements`, () => {
arr.push(1)
})
}

Expand All @@ -76,17 +141,14 @@ for (let amount = 1e1; amount < 1e4; amount *= 10) {
for (let i = 0, n = amount; i < n; i++) {
rawArray.push(i)
}
const r = shallowRef(rawArray)
const c = computed(() => {
return r.value.reduce((v, a) => a + v, 0)
const arr = reactive(rawArray)
let sum = 0
effect(() => {
arr.forEach(x => (sum += x))
})

bench(`reduce *raw* array, manually triggered, ${amount} elements`, () => {
for (let i = 0, n = rawArray.length; i < n; i++) {
rawArray[i]++
}
triggerRef(r)
c.value
bench(`push() trigger, tracked via forEach, ${amount} elements`, () => {
arr.push(1)
})
}
}
Loading

0 comments on commit 70196a4

Please sign in to comment.