I would like to measure execution time of a webworker that computes factorization. The webworker is messaging live results and once computations are terminated, the webworker sends a 'finished' message. I used promise to do this in my react app.
useEffect(() => {
const measureTimeStart = performance.now();
(async () => {
try {
await new Promise(resolve => {
const worker = new Worker(new URL('facto.js', import.meta.url));
worker.postMessage(number);
worker.onmessage = message => { //streaming live results
const { facto, status } = message.data;
setResults({ ...facto }); //adding them to React state
if (status === 'finished') {
resolve();
worker.terminate();
};
};
});
} catch (error) {
console.log(error)
}
})();
const measureTimeEnd = performance.now();
setExecutionTime(Math.round((measureTimeEnd - measureTimeStart) * 1000) / 1000 + ' ms');
}, [number]); //number to factorize
However, performance.now() doesn't wait that the promise resolves and consequently gives me arbitrary timing. Why? thanks.
useEffect(() => {
runWebWorker()
}, [number])
async function runWebWorker() {
const start = performance.now()
await ...
const end = performance.now()
}
Alternatively, have your worker send performance data, which is more measurable and excludes the postMessage queue latency.
You need to wait for the promise to resolve before measuring the time. Either with finally or then
useEffect(() => {
const measureTimeStart = performance.now();
(async () => {
try {
await new Promise(resolve => {
const worker = new Worker(new URL('facto.js', import.meta.url));
worker.postMessage(number);
worker.onmessage = message => { //streaming live results
const { facto, status } = message.data;
setResults({ ...facto }); //adding them to React state
if (status === 'finished') {
resolve();
worker.terminate();
};
};
});
} catch (error) {
console.log(error)
}
})().finally(() => {
const measureTimeEnd = performance.now();
setExecutionTime(Math.round((measureTimeEnd - measureTimeStart) * 1000) / 1000 + ' ms');
});
}, [number]); //number to factorize