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 * 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';
|
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 benchmarks = [
|
||||||
const results = [];
|
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);
|
$.push({}, true);
|
||||||
for (const benchmark of benchmarks) {
|
try {
|
||||||
results.push(await benchmark());
|
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();
|
$.pop();
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(results);
|
console.log('-- Benchmarking Complete --');
|
||||||
}
|
}
|
||||||
|
|
||||||
run_benchmarks();
|
run_benchmarks();
|
||||||
|
Loading…
Reference in new issue