Skip to content

Instantly share code, notes, and snippets.

@mourner
Created June 10, 2020 17:45
Show Gist options
  • Save mourner/442e65ca838d797e89f591c94b81204f to your computer and use it in GitHub Desktop.
Save mourner/442e65ca838d797e89f591c94b81204f to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>Worker Test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#log { font: 14px monospace; }
</style>
</head>
<body>
<div id="log"></div>
<script>
async function runBench(numWorkers, done) {
return new Promise(resolve => {
const start = Date.now();
const workers = [];
const results = [];
let numFinished = 0;
for (let i = 0; i < numWorkers; i++) {
const worker = new Worker('./worker.js');
worker.onmessage = (e) => {
results.push(e.data);
worker.terminate();
if (++numFinished === numWorkers) {
resolve(results);
}
}
worker.postMessage(start);
workers[i] = worker;
}
});
}
let frameId;
function frame() {
const start = performance.now();
while (performance.now() - start < 15) {}
frameId = requestAnimationFrame(frame);
}
frameId = requestAnimationFrame(frame);
function log(msg) {
const logEl = document.getElementById('log');
logEl.innerHTML += `${msg}<br>`;
}
(async () => {
log(`hardwareConcurrency: ${navigator.hardwareConcurrency}<br>`);
const maxWorkers = 8;
await runBench(1); // warmup
let baseline, baselineWork;
for (let numWorkers = 1; numWorkers <= maxWorkers; numWorkers++) {
log(`Running ${numWorkers} workers:`);
const start = Date.now();
const times = await runBench(numWorkers);
const total = Date.now() - start;
if (numWorkers === 1) {
baseline = total;
baselineWork = times[0].work;
}
for (const [i, {init, work}] of Object.entries(times)) {
log(`worker ${i}: ${init}ms init + ${work}ms work`);
}
log(`first result: ${times[0].init + times[0].work}ms`);
log(`single slowdown: ${(times[0].work / baselineWork).toLocaleString()}x`);
log(`parallel speedup: ${(numWorkers * baseline / total).toLocaleString()}x<br>`);
}
log('done');
cancelAnimationFrame(frameId);
})();
</script>
</body>
</html>
function* primes() {
yield 2; yield 3; yield 5; yield 7;
const sieve = new Map();
const ps = primes();
ps.next();
ps.next();
for (let p = 3, i = 9; true; i += 2) {
let s = sieve.get(i);
if (s !== undefined) {
sieve.delete(i);
} else if (i < p * p) {
yield i;
continue;
} else {
s = 2 * p;
p = ps.next().value;
}
let k = i + s;
while (sieve.has(k)) k += s;
sieve.set(k, s);
}
}
const N = 1000000;
onmessage = (e) => {
const start = Date.now();
const init = start - e.data;
const ps = primes();
for (let i = 0; i < N; i++) ps.next();
const work = Date.now() - start;
self.postMessage({init, work});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment