|
<!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> |
usignal 0.4.x has async effect so if you want to compare apples with apples you need to use
https://unpkg.com/usignal/esm/async.js?module
as the async version is meant for browsers / DOM.That is:
Te fact computed are lazy has not much to do with this benchmark but if this benchmark reveal an issue with usignal you are welcome to file an issue. I'll have a look at what you expect and what's different in usignal but you should start with updating the comparison using the async version.
edit I’m not sure I understand what I’m looking at … it feels like you are expecting all computed to side effect invokes of other computed so, in that regards, this demo shows usignal doesn’t do that, like the leak test shows it computes 2 times instead of 53 … do you have by any chance a minimal situation that shows usignal fails expectations? Not like debugging loops, you know … thanks.