mirror of https://github.com/sveltejs/svelte
parent
60e19c7c04
commit
c7f6805c37
@ -0,0 +1,60 @@
|
||||
import { assert, fastest_test } from '../../utils.js';
|
||||
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
|
||||
import { busy } from './util.js';
|
||||
|
||||
function setup() {
|
||||
let head = $.source(0);
|
||||
let computed1 = $.derived(() => $.get(head));
|
||||
let computed2 = $.derived(() => ($.get(computed1), 0));
|
||||
let computed3 = $.derived(() => (busy(), $.get(computed2) + 1)); // heavy computation
|
||||
let computed4 = $.derived(() => $.get(computed3) + 2);
|
||||
let computed5 = $.derived(() => $.get(computed4) + 3);
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(computed5);
|
||||
busy(); // heavy side effect
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert($.get(computed5) === 6);
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(computed5) === 6);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_avoidable() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_avoidable',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
import { assert, fastest_test } from '../../utils.js';
|
||||
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
|
||||
|
||||
function setup() {
|
||||
let head = $.source(0);
|
||||
let last = head;
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
for (let i = 0; i < 50; i++) {
|
||||
let current = $.derived(() => {
|
||||
return $.get(head) + i;
|
||||
});
|
||||
let current2 = $.derived(() => {
|
||||
return $.get(current) + 1;
|
||||
});
|
||||
$.render_effect(() => {
|
||||
$.get(current2);
|
||||
counter++;
|
||||
});
|
||||
last = current2;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
counter = 0
|
||||
for (let i = 0; i < 50; i++) {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(last) === i + 50);
|
||||
}
|
||||
assert(counter === 50 * 50);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_broad() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_broad',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
import { assert, fastest_test } from '../../utils.js';
|
||||
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
|
||||
|
||||
let len = 50;
|
||||
const iter = 50;
|
||||
|
||||
function setup() {
|
||||
let head = $.source(0);
|
||||
let current = head;
|
||||
for (let i = 0; i < len; i++) {
|
||||
let c = current;
|
||||
current = $.derived(() => {
|
||||
return $.get(c) + 1;
|
||||
});
|
||||
}
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(current);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
counter = 0
|
||||
for (let i = 0; i < iter; i++) {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(current) === len + i);
|
||||
}
|
||||
assert(counter === iter);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_deep() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_deep',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
import { assert, fastest_test } from '../../utils.js';
|
||||
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
|
||||
|
||||
let width = 5;
|
||||
|
||||
function setup() {
|
||||
let head = $.source(0);
|
||||
let current = [];
|
||||
for (let i = 0; i < width; i++) {
|
||||
current.push(
|
||||
$.derived(() => {
|
||||
return $.get(head) + 1;
|
||||
})
|
||||
);
|
||||
}
|
||||
let sum = $.derived(() => {
|
||||
return current.map((x) => $.get(x)).reduce((a, b) => a + b, 0);
|
||||
});
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(sum);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert($.get(sum) === 2 * width);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 500; i++) {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(sum) === (i + 1) * width);
|
||||
}
|
||||
assert(counter === 500);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_diamond() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_diamond',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
import { assert, fastest_test } from '../../utils.js';
|
||||
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
|
||||
|
||||
function setup() {
|
||||
let heads = new Array(100).fill(null).map((_) => $.source(0));
|
||||
const mux = $.derived(() => {
|
||||
return Object.fromEntries(heads.map((h) => $.get(h)).entries());
|
||||
});
|
||||
const splited = heads
|
||||
.map((_, index) => $.derived(() => $.get(mux)[index]))
|
||||
.map((x) => $.derived(() => $.get(x) + 1));
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
splited.forEach((x) => {
|
||||
$.render_effect(() => {
|
||||
$.get(x);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
$.flush_sync(() => {
|
||||
$.set(heads[i], i);
|
||||
});
|
||||
assert($.get(splited[i]) === i + 1);
|
||||
}
|
||||
for (let i = 0; i < 10; i++) {
|
||||
$.flush_sync(() => {
|
||||
$.set(heads[i], i * 2);
|
||||
});
|
||||
assert($.get(splited[i]) === i * 2 + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_mux() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_mux',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
import { assert, fastest_test } from '../../utils.js';
|
||||
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
|
||||
|
||||
let size = 30;
|
||||
|
||||
function setup() {
|
||||
let head = $.source(0);
|
||||
let current = $.derived(() => {
|
||||
let result = 0;
|
||||
for (let i = 0; i < size; i++) {
|
||||
result += $.get(head);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(current);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert($.get(current) === size);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 100; i++) {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(current) === i * size);
|
||||
}
|
||||
assert(counter === 100);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_repeated() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_repeated',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
import { assert, fastest_test } from '../../utils.js';
|
||||
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
|
||||
|
||||
let width = 10;
|
||||
|
||||
function count(number) {
|
||||
return new Array(number)
|
||||
.fill(0)
|
||||
.map((_, i) => i + 1)
|
||||
.reduce((x, y) => x + y, 0);
|
||||
}
|
||||
|
||||
function setup() {
|
||||
let head = $.source(0);
|
||||
let current = head;
|
||||
let list = [];
|
||||
for (let i = 0; i < width; i++) {
|
||||
let c = current;
|
||||
list.push(current);
|
||||
current = $.derived(() => {
|
||||
return $.get(c) + 1;
|
||||
});
|
||||
}
|
||||
let sum = $.derived(() => {
|
||||
return list.map((x) => $.get(x)).reduce((a, b) => a + b, 0);
|
||||
});
|
||||
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(sum);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
const constant = count(width);
|
||||
$.flush_sync(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert($.get(sum) === constant);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 100; i++) {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(sum) === constant - width + i * width);
|
||||
}
|
||||
assert(counter === 100);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_triangle() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_triangle',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
import { assert, fastest_test } from '../../utils.js';
|
||||
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
|
||||
|
||||
function setup() {
|
||||
let head = $.source(0);
|
||||
const double = $.derived(() => $.get(head) * 2);
|
||||
const inverse = $.derived(() => -$.get(head));
|
||||
let current = $.derived(() => {
|
||||
let result = 0;
|
||||
for (let i = 0; i < 20; i++) {
|
||||
result += $.get(head) % 2 ? $.get(double) : $.get(inverse);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(current);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert($.get(current) === 40);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 100; i++) {
|
||||
$.flush_sync(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
}
|
||||
assert(counter === 100);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_unstable() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_unstable',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
|
||||
export function busy() {
|
||||
let a = 0;
|
||||
for (let i = 0; i < 1_00; i++) {
|
||||
a++;
|
||||
}
|
||||
}
|
@ -1,19 +1,48 @@
|
||||
import * as $ from '../packages/svelte/src/internal/client/index.js';
|
||||
import { kairo_avoidable } from './benchmarks/kairo/kairo_avoidable.js';
|
||||
import { kairo_broad } from './benchmarks/kairo/kairo_broad.js';
|
||||
import { kairo_deep } from './benchmarks/kairo/kairo_deep.js';
|
||||
import { kairo_diamond } from './benchmarks/kairo/kairo_diamond.js';
|
||||
import { kairo_mux } from './benchmarks/kairo/kairo_mux.js';
|
||||
import { kairo_repeated } from './benchmarks/kairo/kairo_repeated.js';
|
||||
import { kairo_triangle } from './benchmarks/kairo/kairo_triangle.js';
|
||||
import { kairo_unstable } from './benchmarks/kairo/kairo_unstable.js';
|
||||
import { mol_bench } from './benchmarks/mol_bench.js';
|
||||
|
||||
const benchmarks = [mol_bench];
|
||||
// This benchmark has been adapted from the js-reactivity-benchmark (https://github.com/milomg/js-reactivity-benchmark)
|
||||
// Not all tests are the same, and many parts have been tweaked to capture different data.
|
||||
|
||||
async function run_benchmarks() {
|
||||
const results = [];
|
||||
const benchmarks = [
|
||||
kairo_avoidable,
|
||||
kairo_broad,
|
||||
kairo_deep,
|
||||
kairo_diamond,
|
||||
kairo_triangle,
|
||||
kairo_mux,
|
||||
kairo_repeated,
|
||||
kairo_unstable,
|
||||
mol_bench
|
||||
];
|
||||
|
||||
async function run_benchmarks() {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('-- Benchmarking Started --');
|
||||
$.push({}, true);
|
||||
for (const benchmark of benchmarks) {
|
||||
results.push(await benchmark());
|
||||
try {
|
||||
for (const benchmark of benchmarks) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(await benchmark());
|
||||
}
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('-- Benchmarking Failed --');
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
$.pop();
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(results);
|
||||
console.log('-- Benchmarking Complete --');
|
||||
}
|
||||
|
||||
run_benchmarks();
|
||||
|
Loading…
Reference in new issue