Skip to content

Commit c7f6805

Browse files
authored
chore: add more benchmarks (#12094)
chore: add more benchmarks
1 parent 60e19c7 commit c7f6805

File tree

13 files changed

+616
-14
lines changed

13 files changed

+616
-14
lines changed

.github/workflows/ci.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,17 @@ jobs:
6060
- name: build and check generated types
6161
if: (${{ success() }} || ${{ failure() }}) # ensures this step runs even if previous steps fail
6262
run: pnpm build && { [ "`git status --porcelain=v1`" == "" ] || (echo "Generated types have changed — please regenerate types locally and commit the changes after you have reviewed them"; git diff; exit 1); }
63+
Benchmarks:
64+
runs-on: ubuntu-latest
65+
timeout-minutes: 15
66+
steps:
67+
- uses: actions/checkout@v3
68+
- uses: pnpm/action-setup@v4
69+
- uses: actions/setup-node@v3
70+
with:
71+
node-version: 18
72+
cache: pnpm
73+
- run: pnpm install --frozen-lockfile
74+
- run: pnpm bench
75+
env:
76+
CI: true
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { assert, fastest_test } from '../../utils.js';
2+
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
3+
import { busy } from './util.js';
4+
5+
function setup() {
6+
let head = $.source(0);
7+
let computed1 = $.derived(() => $.get(head));
8+
let computed2 = $.derived(() => ($.get(computed1), 0));
9+
let computed3 = $.derived(() => (busy(), $.get(computed2) + 1)); // heavy computation
10+
let computed4 = $.derived(() => $.get(computed3) + 2);
11+
let computed5 = $.derived(() => $.get(computed4) + 3);
12+
13+
const destroy = $.effect_root(() => {
14+
$.render_effect(() => {
15+
$.get(computed5);
16+
busy(); // heavy side effect
17+
});
18+
});
19+
20+
return {
21+
destroy,
22+
run() {
23+
$.flush_sync(() => {
24+
$.set(head, 1);
25+
});
26+
assert($.get(computed5) === 6);
27+
for (let i = 0; i < 1000; i++) {
28+
$.flush_sync(() => {
29+
$.set(head, i);
30+
});
31+
assert($.get(computed5) === 6);
32+
}
33+
}
34+
};
35+
}
36+
37+
export async function kairo_avoidable() {
38+
// Do 10 loops to warm up JIT
39+
for (let i = 0; i < 10; i++) {
40+
const { run, destroy } = setup();
41+
run();
42+
destroy();
43+
}
44+
45+
const { run, destroy } = setup();
46+
47+
const { timing } = await fastest_test(10, () => {
48+
for (let i = 0; i < 100; i++) {
49+
run();
50+
}
51+
});
52+
53+
destroy();
54+
55+
return {
56+
benchmark: 'kairo_avoidable',
57+
time: timing.time.toFixed(2),
58+
gc_time: timing.gc_time.toFixed(2)
59+
};
60+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { assert, fastest_test } from '../../utils.js';
2+
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
3+
4+
function setup() {
5+
let head = $.source(0);
6+
let last = head;
7+
let counter = 0;
8+
9+
const destroy = $.effect_root(() => {
10+
for (let i = 0; i < 50; i++) {
11+
let current = $.derived(() => {
12+
return $.get(head) + i;
13+
});
14+
let current2 = $.derived(() => {
15+
return $.get(current) + 1;
16+
});
17+
$.render_effect(() => {
18+
$.get(current2);
19+
counter++;
20+
});
21+
last = current2;
22+
}
23+
});
24+
25+
return {
26+
destroy,
27+
run() {
28+
$.flush_sync(() => {
29+
$.set(head, 1);
30+
});
31+
counter = 0
32+
for (let i = 0; i < 50; i++) {
33+
$.flush_sync(() => {
34+
$.set(head, i);
35+
});
36+
assert($.get(last) === i + 50);
37+
}
38+
assert(counter === 50 * 50);
39+
}
40+
};
41+
}
42+
43+
export async function kairo_broad() {
44+
// Do 10 loops to warm up JIT
45+
for (let i = 0; i < 10; i++) {
46+
const { run, destroy } = setup();
47+
run();
48+
destroy();
49+
}
50+
51+
const { run, destroy } = setup();
52+
53+
const { timing } = await fastest_test(10, () => {
54+
for (let i = 0; i < 100; i++) {
55+
run();
56+
}
57+
});
58+
59+
destroy();
60+
61+
return {
62+
benchmark: 'kairo_broad',
63+
time: timing.time.toFixed(2),
64+
gc_time: timing.gc_time.toFixed(2)
65+
};
66+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { assert, fastest_test } from '../../utils.js';
2+
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
3+
4+
let len = 50;
5+
const iter = 50;
6+
7+
function setup() {
8+
let head = $.source(0);
9+
let current = head;
10+
for (let i = 0; i < len; i++) {
11+
let c = current;
12+
current = $.derived(() => {
13+
return $.get(c) + 1;
14+
});
15+
}
16+
let counter = 0;
17+
18+
const destroy = $.effect_root(() => {
19+
$.render_effect(() => {
20+
$.get(current);
21+
counter++;
22+
});
23+
});
24+
25+
return {
26+
destroy,
27+
run() {
28+
$.flush_sync(() => {
29+
$.set(head, 1);
30+
});
31+
counter = 0
32+
for (let i = 0; i < iter; i++) {
33+
$.flush_sync(() => {
34+
$.set(head, i);
35+
});
36+
assert($.get(current) === len + i);
37+
}
38+
assert(counter === iter);
39+
}
40+
};
41+
}
42+
43+
export async function kairo_deep() {
44+
// Do 10 loops to warm up JIT
45+
for (let i = 0; i < 10; i++) {
46+
const { run, destroy } = setup();
47+
run();
48+
destroy();
49+
}
50+
51+
const { run, destroy } = setup();
52+
53+
const { timing } = await fastest_test(10, () => {
54+
for (let i = 0; i < 100; i++) {
55+
run();
56+
}
57+
});
58+
59+
destroy();
60+
61+
return {
62+
benchmark: 'kairo_deep',
63+
time: timing.time.toFixed(2),
64+
gc_time: timing.gc_time.toFixed(2)
65+
};
66+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { assert, fastest_test } from '../../utils.js';
2+
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
3+
4+
let width = 5;
5+
6+
function setup() {
7+
let head = $.source(0);
8+
let current = [];
9+
for (let i = 0; i < width; i++) {
10+
current.push(
11+
$.derived(() => {
12+
return $.get(head) + 1;
13+
})
14+
);
15+
}
16+
let sum = $.derived(() => {
17+
return current.map((x) => $.get(x)).reduce((a, b) => a + b, 0);
18+
});
19+
let counter = 0;
20+
21+
const destroy = $.effect_root(() => {
22+
$.render_effect(() => {
23+
$.get(sum);
24+
counter++;
25+
});
26+
});
27+
28+
return {
29+
destroy,
30+
run() {
31+
$.flush_sync(() => {
32+
$.set(head, 1);
33+
});
34+
assert($.get(sum) === 2 * width);
35+
counter = 0;
36+
for (let i = 0; i < 500; i++) {
37+
$.flush_sync(() => {
38+
$.set(head, i);
39+
});
40+
assert($.get(sum) === (i + 1) * width);
41+
}
42+
assert(counter === 500);
43+
}
44+
};
45+
}
46+
47+
export async function kairo_diamond() {
48+
// Do 10 loops to warm up JIT
49+
for (let i = 0; i < 10; i++) {
50+
const { run, destroy } = setup();
51+
run();
52+
destroy();
53+
}
54+
55+
const { run, destroy } = setup();
56+
57+
const { timing } = await fastest_test(10, () => {
58+
for (let i = 0; i < 100; i++) {
59+
run();
60+
}
61+
});
62+
63+
destroy();
64+
65+
return {
66+
benchmark: 'kairo_diamond',
67+
time: timing.time.toFixed(2),
68+
gc_time: timing.gc_time.toFixed(2)
69+
};
70+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { assert, fastest_test } from '../../utils.js';
2+
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
3+
4+
function setup() {
5+
let heads = new Array(100).fill(null).map((_) => $.source(0));
6+
const mux = $.derived(() => {
7+
return Object.fromEntries(heads.map((h) => $.get(h)).entries());
8+
});
9+
const splited = heads
10+
.map((_, index) => $.derived(() => $.get(mux)[index]))
11+
.map((x) => $.derived(() => $.get(x) + 1));
12+
13+
const destroy = $.effect_root(() => {
14+
splited.forEach((x) => {
15+
$.render_effect(() => {
16+
$.get(x);
17+
});
18+
});
19+
});
20+
21+
return {
22+
destroy,
23+
run() {
24+
for (let i = 0; i < 10; i++) {
25+
$.flush_sync(() => {
26+
$.set(heads[i], i);
27+
});
28+
assert($.get(splited[i]) === i + 1);
29+
}
30+
for (let i = 0; i < 10; i++) {
31+
$.flush_sync(() => {
32+
$.set(heads[i], i * 2);
33+
});
34+
assert($.get(splited[i]) === i * 2 + 1);
35+
}
36+
}
37+
};
38+
}
39+
40+
export async function kairo_mux() {
41+
// Do 10 loops to warm up JIT
42+
for (let i = 0; i < 10; i++) {
43+
const { run, destroy } = setup();
44+
run();
45+
destroy();
46+
}
47+
48+
const { run, destroy } = setup();
49+
50+
const { timing } = await fastest_test(10, () => {
51+
for (let i = 0; i < 100; i++) {
52+
run();
53+
}
54+
});
55+
56+
destroy();
57+
58+
return {
59+
benchmark: 'kairo_mux',
60+
time: timing.time.toFixed(2),
61+
gc_time: timing.gc_time.toFixed(2)
62+
};
63+
}

0 commit comments

Comments
 (0)