chore: add ssr benchmark suite (#14361)

* chore: add ssr benchmark suite

* lint

* Update benchmarking/run.js

Co-authored-by: Rich Harris <rich.harris@vercel.com>

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/14363/head
Dominic Gannaway 10 months ago committed by GitHub
parent 6e8267f462
commit f6117bb328
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1 @@
output

@ -1,15 +1,12 @@
import {
kairo_avoidable_owned,
kairo_avoidable_unowned
} from './benchmarks/kairo/kairo_avoidable.js';
import { kairo_broad_owned, kairo_broad_unowned } from './benchmarks/kairo/kairo_broad.js';
import { kairo_deep_owned, kairo_deep_unowned } from './benchmarks/kairo/kairo_deep.js';
import { kairo_diamond_owned, kairo_diamond_unowned } from './benchmarks/kairo/kairo_diamond.js';
import { kairo_mux_unowned, kairo_mux_owned } from './benchmarks/kairo/kairo_mux.js';
import { kairo_repeated_unowned, kairo_repeated_owned } from './benchmarks/kairo/kairo_repeated.js';
import { kairo_triangle_owned, kairo_triangle_unowned } from './benchmarks/kairo/kairo_triangle.js';
import { kairo_unstable_owned, kairo_unstable_unowned } from './benchmarks/kairo/kairo_unstable.js';
import { mol_bench_owned, mol_bench_unowned } from './benchmarks/mol_bench.js';
import { kairo_avoidable_owned, kairo_avoidable_unowned } from './kairo/kairo_avoidable.js';
import { kairo_broad_owned, kairo_broad_unowned } from './kairo/kairo_broad.js';
import { kairo_deep_owned, kairo_deep_unowned } from './kairo/kairo_deep.js';
import { kairo_diamond_owned, kairo_diamond_unowned } from './kairo/kairo_diamond.js';
import { kairo_mux_unowned, kairo_mux_owned } from './kairo/kairo_mux.js';
import { kairo_repeated_unowned, kairo_repeated_owned } from './kairo/kairo_repeated.js';
import { kairo_triangle_owned, kairo_triangle_unowned } from './kairo/kairo_triangle.js';
import { kairo_unstable_owned, kairo_unstable_unowned } from './kairo/kairo_unstable.js';
import { mol_bench_owned, mol_bench_unowned } from './mol_bench.js';
import {
sbench_create_0to1,
sbench_create_1000to1,
@ -21,12 +18,12 @@ import {
sbench_create_2to1,
sbench_create_4to1,
sbench_create_signals
} from './benchmarks/sbench.js';
} from './sbench.js';
// 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.
export const benchmarks = [
export const reactivity_benchmarks = [
sbench_create_signals,
sbench_create_0to1,
sbench_create_1to1,

@ -1,5 +1,5 @@
import { assert, fastest_test } from '../../utils.js';
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
import { assert, fastest_test } from '../../../utils.js';
import * as $ from 'svelte/internal/client';
import { busy } from './util.js';
function setup() {

@ -1,5 +1,5 @@
import { assert, fastest_test } from '../../utils.js';
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
import { assert, fastest_test } from '../../../utils.js';
import * as $ from 'svelte/internal/client';
function setup() {
let head = $.state(0);

@ -1,5 +1,5 @@
import { assert, fastest_test } from '../../utils.js';
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
import { assert, fastest_test } from '../../../utils.js';
import * as $ from 'svelte/internal/client';
let len = 50;
const iter = 50;

@ -1,5 +1,5 @@
import { assert, fastest_test } from '../../utils.js';
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
import { assert, fastest_test } from '../../../utils.js';
import * as $ from 'svelte/internal/client';
let width = 5;

@ -1,5 +1,5 @@
import { assert, fastest_test } from '../../utils.js';
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
import { assert, fastest_test } from '../../../utils.js';
import * as $ from 'svelte/internal/client';
function setup() {
let heads = new Array(100).fill(null).map((_) => $.state(0));

@ -1,5 +1,5 @@
import { assert, fastest_test } from '../../utils.js';
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
import { assert, fastest_test } from '../../../utils.js';
import * as $ from 'svelte/internal/client';
let size = 30;

@ -1,5 +1,5 @@
import { assert, fastest_test } from '../../utils.js';
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
import { assert, fastest_test } from '../../../utils.js';
import * as $ from 'svelte/internal/client';
let width = 10;

@ -1,5 +1,5 @@
import { assert, fastest_test } from '../../utils.js';
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
import { assert, fastest_test } from '../../../utils.js';
import * as $ from 'svelte/internal/client';
function setup() {
let head = $.state(0);

@ -1,5 +1,5 @@
import { assert, fastest_test } from '../utils.js';
import * as $ from '../../packages/svelte/src/internal/client/index.js';
import { assert, fastest_test } from '../../utils.js';
import * as $ from 'svelte/internal/client';
/**
* @param {number} n

@ -1,5 +1,5 @@
import { fastest_test } from '../utils.js';
import * as $ from '../../packages/svelte/src/internal/client/index.js';
import { fastest_test } from '../../utils.js';
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
const COUNT = 1e5;

@ -0,0 +1,3 @@
import { wrapper_bench } from './wrapper/wrapper_bench.js';
export const ssr_benchmarks = [wrapper_bench];

@ -0,0 +1,31 @@
<script>
const wrapperWidth = 960;
const wrapperHeight = 720;
const cellSize = 10;
const centerX = wrapperWidth / 2;
const centerY = wrapperHeight / 2;
let angle = 0;
let radius = 0;
let tiles = [];
const step = cellSize;
while (radius < Math.min(wrapperWidth, wrapperHeight) / 2) {
let x = centerX + Math.cos(angle) * radius;
let y = centerY + Math.sin(angle) * radius;
if (x >= 0 && x <= wrapperWidth - cellSize && y >= 0 && y <= wrapperHeight - cellSize) {
tiles.push({ x, y });
}
angle += 0.2;
radius += step * 0.015;
}
</script>
<div id="wrapper">
{#each tiles as { x, y }}
<div class="tile" style="left: {x.toFixed(2)}px; top: {y.toFixed(2)}px;"></div>
{/each}
</div>

@ -0,0 +1,36 @@
import { render } from 'svelte/server';
import { fastest_test, read_file, write } from '../../../utils.js';
import { compile } from 'svelte/compiler';
const dir = `${process.cwd()}/benchmarking/benchmarks/ssr/wrapper`;
async function compile_svelte() {
const output = compile(read_file(`${dir}/App.svelte`), {
generate: 'server'
});
write(`${dir}/output/App.js`, output.js.code);
const module = await import(`${dir}/output/App.js`);
return module.default;
}
export async function wrapper_bench() {
const App = await compile_svelte();
// Do 3 loops to warm up JIT
for (let i = 0; i < 3; i++) {
render(App);
}
const { timing } = await fastest_test(10, () => {
for (let i = 0; i < 100; i++) {
render(App);
}
});
return {
benchmark: 'wrapper_bench',
time: timing.time.toFixed(2),
gc_time: timing.gc_time.toFixed(2)
};
}

@ -1,30 +1,53 @@
import * as $ from '../packages/svelte/src/internal/client/index.js';
import { benchmarks } from './benchmarks.js';
import { reactivity_benchmarks } from './benchmarks/reactivity/index.js';
import { ssr_benchmarks } from './benchmarks/ssr/index.js';
let total_time = 0;
let total_gc_time = 0;
const suites = [
{ benchmarks: reactivity_benchmarks, name: 'reactivity benchmarks' },
{ benchmarks: ssr_benchmarks, name: 'server-side rendering benchmarks' }
];
// eslint-disable-next-line no-console
console.log('-- Benchmarking Started --');
console.log('\x1b[1m', '-- Benchmarking Started --', '\x1b[0m');
$.push({}, true);
try {
for (const benchmark of benchmarks) {
const results = await benchmark();
for (const { benchmarks, name } of suites) {
let suite_time = 0;
let suite_gc_time = 0;
// eslint-disable-next-line no-console
console.log(`\nRunning ${name}...\n`);
for (const benchmark of benchmarks) {
const results = await benchmark();
// eslint-disable-next-line no-console
console.log(results);
total_time += Number(results.time);
total_gc_time += Number(results.gc_time);
suite_time += Number(results.time);
suite_gc_time += Number(results.gc_time);
}
console.log(`\nFinished ${name}.\n`);
// eslint-disable-next-line no-console
console.log(results);
total_time += Number(results.time);
total_gc_time += Number(results.gc_time);
console.log({
suite_time: suite_time.toFixed(2),
suite_gc_time: suite_gc_time.toFixed(2)
});
}
} catch (e) {
// eslint-disable-next-line no-console
console.error('-- Benchmarking Failed --');
console.log('\x1b[1m', '\n-- Benchmarking Failed --\n', '\x1b[0m');
// eslint-disable-next-line no-console
console.error(e);
process.exit(1);
}
$.pop();
// eslint-disable-next-line no-console
console.log('-- Benchmarking Complete --');
console.log('\x1b[1m', '\n-- Benchmarking Complete --\n', '\x1b[0m');
// eslint-disable-next-line no-console
console.log({
total_time: total_time.toFixed(2),

@ -1,5 +1,7 @@
import { performance, PerformanceObserver } from 'node:perf_hooks';
import v8 from 'v8-natives';
import * as fs from 'node:fs';
import * as path from 'node:path';
// Credit to https://github.com/milomg/js-reactivity-benchmark for the logic for timing + GC tracking.
@ -96,3 +98,22 @@ export function assert(a) {
throw new Error('Assertion failed');
}
}
/**
* @param {string} file
*/
export function read_file(file) {
return fs.readFileSync(file, 'utf-8').replace(/\r\n/g, '\n');
}
/**
* @param {string} file
* @param {string} contents
*/
export function write(file, contents) {
try {
fs.mkdirSync(path.dirname(file), { recursive: true });
} catch {}
fs.writeFileSync(file, contents);
}

Loading…
Cancel
Save