const workerFunction = () => { self.onmessage = (message) => { const isPrime = (candidate) => { for (let i = 2; i <= Math.floor(Math.sqrt(candidate)); i++) { if (candidate % i === 0) return false; } return true; } let { offset, length } = message.data; let view = new Uint8Array(length); let count = 0; for (let i = 0; i < length; i++) { let candidate = i + offset + 2; let result = isPrime(candidate); if (result) count++; view[i] = result; } self.postMessage({ buffer: view.buffer, count, offset, length }, [view.buffer]); } } const hackFunctionToBuffer = (f) => { return URL.createObjectURL(new Blob([`(${f.toString()})()`], { type: 'application/javascript' })) } const startTest = () => { // number of workers we'll create in parallel const totalWorkers = 4 const bufferSize = 1024 * 1024 * 2 // same buffer size as before let remaining = bufferSize; let buffer = new ArrayBuffer(remaining) let view = new Uint8Array(buffer); let count = 0; let offset = 0; let workerBlob = hackFunctionToBuffer(workerFunction); performance.mark('startTest'); while (remaining) { let length = Math.min(remaining, bufferSize / totalWorkers); let worker = new Worker(workerBlob); worker.onmessage = (message) => { let { data } = message; view.set(new Uint8Array(data.buffer), data.offset); count += data.count; if (data.offset + data.length === buffer.byteLength) { performance.mark('endTest') performance.measure('primes', 'startTest', 'endTest'); document.getElementById('performance').innerHTML = `Found ${message.data.count} in ${performance.getEntriesByName('primes')[0].duration} ms`; } } worker.postMessage({ offset, length }); remaining -= length; offset += length; } } document.getElementById('test').addEventListener('click', startTest);
<button id="test">Start Test</button> Results:<br /> <pre id="performance">Nothing yet...</pre>