forked from milomg/js-reactivity-benchmark
-
Notifications
You must be signed in to change notification settings - Fork 5
/
cellxBench.ts
142 lines (117 loc) · 3.61 KB
/
cellxBench.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// The following is an implementation of the cellx benchmark https://github.com/Riim/cellx/blob/master/perf/perf.html
import { logPerfResult } from "./util/perfLogging";
import { Computed, ReactiveFramework } from "./util/reactiveFramework";
const cellx = (framework: ReactiveFramework, layers: number) => {
return framework.withBuild(() => {
const start = {
prop1: framework.signal(1),
prop2: framework.signal(2),
prop3: framework.signal(3),
prop4: framework.signal(4),
};
let layer: {
prop1: Computed<number>;
prop2: Computed<number>;
prop3: Computed<number>;
prop4: Computed<number>;
} = start;
for (let i = layers; i > 0; i--) {
const m = layer;
const s = {
prop1: framework.computed(() => m.prop2.read()),
prop2: framework.computed(() => m.prop1.read() - m.prop3.read()),
prop3: framework.computed(() => m.prop2.read() + m.prop4.read()),
prop4: framework.computed(() => m.prop3.read()),
};
// [@vue/reactivity] If you remove these 4 lines, the tests seem to work fine.
framework.effect(() => s.prop1.read());
framework.effect(() => s.prop2.read());
framework.effect(() => s.prop3.read());
framework.effect(() => s.prop4.read());
s.prop1.read();
s.prop2.read();
s.prop3.read();
s.prop4.read();
layer = s;
}
const end = layer;
const startTime = performance.now();
const before = [
end.prop1.read(),
end.prop2.read(),
end.prop3.read(),
end.prop4.read(),
] as const;
framework.withBatch(() => {
console.log("start batch write");
// [@vue/reactivity] this line seems to be where `@vue/reactivity` hangs.
start.prop1.write(4);
start.prop2.write(3);
start.prop3.write(2);
start.prop4.write(1);
console.log("end batch write");
});
const after = [
end.prop1.read(),
end.prop2.read(),
end.prop3.read(),
end.prop4.read(),
] as const;
const endTime = performance.now();
const elapsedTime = endTime - startTime;
return [elapsedTime, before, after] as const;
});
};
const arraysEqual = (a: readonly number[], b: readonly number[]) => {
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
};
type BenchmarkResults = [
readonly [number, number, number, number],
readonly [number, number, number, number],
];
export const cellxbench = (framework: ReactiveFramework) => {
const expected: Record<number, BenchmarkResults> = {
1000: [
[-3, -6, -2, 2],
[-2, -4, 2, 3],
],
2500: [
[-3, -6, -2, 2],
[-2, -4, 2, 3],
],
5000: [
[2, 4, -1, -6],
[-2, 1, -4, -4],
],
};
const results: Record<number, BenchmarkResults> = {};
for (const layers in expected) {
let total = 0;
for (let i = 0; i < 10; i++) {
const [elapsed, before, after] = cellx(framework, Number(layers));
results[layers] = [before, after];
total += elapsed;
}
logPerfResult({
framework: framework.name,
test: `cellx${layers}`,
time: total.toFixed(2),
});
}
for (const layers in expected) {
const [before, after] = results[layers];
const [expectedBefore, expectedAfter] = expected[layers];
console.assert(
arraysEqual(before, expectedBefore),
`Expected first layer ${expectedBefore}, found first layer ${before}`
);
console.assert(
arraysEqual(after, expectedAfter),
`Expected last layer ${expectedAfter}, found last layer ${after}`
);
}
};