Skip to content

Instantly share code, notes, and snippets.

@peerreynders
Last active September 14, 2022 14:19
Show Gist options
  • Save peerreynders/f2448bd7b35616beb476db0c09976dbf to your computer and use it in GitHub Desktop.
Save peerreynders/f2448bd7b35616beb476db0c09976dbf to your computer and use it in GitHub Desktop.
µsignal 0.4.2 performance comparison

Sample run on Ubuntu 22.04 LTS [i7-4900MQ CPU @ 2.80GHz/32GB] Chromium 105.0.5195.102

Solid (solid.html)

Created 205760 nodes.
278 ms; sum: 9.11303444731602e+305

@preact/signals (preactive.html)

Created 205760 nodes.
415 ms; sum: 9.11303444731602e+305

µsignal (usignal.html)

252 ms; sum: 9.11303444731602e+305
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>@preact/signals version</title>
<style></style>
</head>
<body>
<script type="module">
import {
signal,
computed,
effect,
} from 'https://unpkg.com/@preact/[email protected]/dist/signals-core.module.js?module';
const fmt = new Intl.NumberFormat([], { maximumFractionDigits: 0 });
const GRAPH_DEPTH = 640;
function makeGraph(sources, depth) {
let nodes = 0;
for (; depth > 0; depth -= 1) {
const left = sources[0];
const right = sources[sources.length - 1];
const nextLevel = [computed(() => 2 * left.value)];
for (
let prev = sources[0], i = 1, current = sources[i];
i < sources.length;
prev = current, i += 1, current = sources[i]
) {
nextLevel[i] = computed(() => prev.value + current.value);
}
nextLevel[sources.length] = computed(() => 3 * right.value);
nodes += nextLevel.length;
sources = nextLevel;
}
console.log(`Created ${nodes} nodes.`);
return sources;
}
function setup() {
// create root signal
const source = signal(1);
const memos = makeGraph([source], GRAPH_DEPTH);
// consume top row of memos
let t0 = performance.now();
effect(() => {
const sum = memos.reduce((acc, memo) => acc + memo.value, 0);
const interval = performance.now() - t0;
console.log(`${fmt.format(interval)} ms; sum: ${sum}`);
});
return (newValue) => {
t0 = performance.now();
source.value = newValue;
};
}
(function run(fn, value) {
if (typeof fn === 'function' && typeof value === 'number') {
fn(value); // e.g. update(2)
return;
}
const update = setup();
setTimeout(run, 0, update, 2);
})();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>SolidJS version</title>
<style></style>
</head>
<body>
<script type="module">
import {
createEffect,
createMemo,
createSignal,
createRoot,
} from 'https://unpkg.com/[email protected]/dist/solid.js?module';
const fmt = new Intl.NumberFormat([], { maximumFractionDigits: 0 });
const GRAPH_DEPTH = 640;
function makeGraph(sources, depth) {
let nodes = 0;
for (; depth > 0; depth -= 1) {
const left = sources[0];
const right = sources[sources.length - 1];
const nextLevel = [createMemo(() => 2 * left())];
for (
let prev = sources[0], i = 1, current = sources[i];
i < sources.length;
prev = current, i += 1, current = sources[i]
) {
nextLevel[i] = createMemo(() => prev() + current());
}
nextLevel[sources.length] = createMemo(() => 3 * right());
nodes += nextLevel.length;
sources = nextLevel;
}
console.log(`Created ${nodes} nodes.`);
return sources;
}
function setup() {
// create root signal
const [source, setSource] = createSignal(1);
const memos = makeGraph([source], GRAPH_DEPTH);
// consume top row of memos
let t0 = performance.now();
createEffect(() => {
const sum = memos.reduce((acc, memo) => acc + memo(), 0);
const interval = performance.now() - t0;
console.log(`${fmt.format(interval)} ms; sum: ${sum}`);
});
return (newValue) => {
t0 = performance.now();
setSource(newValue);
};
}
let dispose;
function run(fn, value) {
if (fn === undefined && dispose) {
dispose();
dispose = undefined;
return;
}
if (typeof fn !== 'function') return;
if (typeof value === 'number') {
fn(value); // e.g. update(2)
setTimeout(run);
return;
}
dispose = fn;
const update = setup();
setTimeout(run, 0, update, 2);
}
createRoot(run);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>µsignal version</title>
<style></style>
</head>
<body>
<script type="module">
import {
signal,
computed,
effect,
} from 'https://unpkg.com/[email protected]/esm/index.js?module';
const fmt = new Intl.NumberFormat([], { maximumFractionDigits: 0 });
const GRAPH_DEPTH = 640;
function makeGraph(sources, depth) {
let nodes = 0;
for (; depth > 0; depth -= 1) {
const left = sources[0];
const right = sources[sources.length - 1];
const nextLevel = [computed(() => 2 * left.value)];
for (
let prev = sources[0], i = 1, current = sources[i];
i < sources.length;
prev = current, i += 1, current = sources[i]
) {
nextLevel[i] = computed(() => prev.value + current.value);
}
nextLevel[sources.length] = computed(() => 3 * right.value);
nodes += nextLevel.length;
sources = nextLevel;
}
console.log(`Created ${nodes} nodes.`);
return sources;
}
function setup() {
// create root signal
const source = signal(1);
const memos = makeGraph([source], GRAPH_DEPTH);
// consume top row of memos
let t0 = performance.now();
effect(() => {
const sum = memos.reduce((acc, memo) => acc + memo.value, 0);
const interval = performance.now() - t0;
console.log(`${fmt.format(interval)} ms; sum: ${sum}`);
});
return (newValue) => {
t0 = performance.now();
source.value = newValue;
};
}
(function run(fn, value) {
if (typeof fn === 'function' && typeof value === 'number') {
fn(value); // e.g. update(2)
return;
}
const update = setup();
setTimeout(run, 0, update, 2);
})();
</script>
</body>
</html>
@WebReflection
Copy link

@peerreynders please update those lame results on top by using https://unpkg.com/usignal/esm/async.js?module instead as import, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment