Learn how to check the performance of an async and sync functions in Javascript.
This question was asked in Atlassian’s frontend interview and if you are preparing for frontend interviews then checkout alpha.learnersbucket.com
To check the performance of the function or any code that runs in Javascript, we basically check how much time it took for the execution and we do that by using performance.now() method that returns the current timestamp.
We will create an async function measurePeformance()
that will take the function as input whose performance has to be evaluated and other props like:
- name – The name of the function or the default alias for the anonymous functions.
- iterations – Number of time the function should be invoked, helps to get the average computation time with high and low time.
- warmup – This flag will be used to run the function once to make sure it is not throwing any error before starting the performance test.
- logResults – This flag will be used to determine if we have to log the results or not.
async function measurePerformance(fn, options = {}) { const { name = fn.name || 'Anonymous Function', iterations = 1, warmup = true, logResults = true } = options; const results = { name, iterations, isAsync: fn.constructor.name === 'AsyncFunction', timings: [], average: 0, min: Infinity, max: -Infinity, total: 0 }; // if warmup enabled if (warmup) { try { await fn(); } catch (error) { console.warn(`Warmup run failed for ${name}:`, error); } } // execute the function for the defined iterations for (let i = 0; i < iterations; i++) { const start = performance.now(); try { await fn(); } catch (error) { console.error(`Error in iteration ${i + 1} for ${name}:`, error); continue; } const end = performance.now(); const duration = end - start; // compute and store the results results.timings.push(duration); results.min = Math.min(results.min, duration); results.max = Math.max(results.max, duration); results.total += duration; } // calculate averages results.average = results.total / results.timings.length; // log results if (logResults) { console.log(`\nPerformance Results for ${name}:`); console.log('----------------------------------------'); console.log(`Type: ${results.isAsync ? 'Async' : 'Sync'}`); console.log(`Iterations: ${iterations}`); console.log(`Average: ${results.average.toFixed(2)}ms`); console.log(`Min: ${results.min.toFixed(2)}ms`); console.log(`Max: ${results.max.toFixed(2)}ms`); console.log('----------------------------------------\n'); } return results; }
Testcase: Normal function
Input: // normal function const syncFunction = () => { let sum = 0; for (let i = 0; i < 1000000; i++) { sum += i; } return sum; }; // measure performance of the normal function measurePerformance(syncFunction, { name: 'Sync Calculation', iterations: 5, warmup: true }); Output: "Performance Results for Sync Calculation:" "----------------------------------------" "Type: Sync" "Iterations: 5" "Average: 10.00ms" "Min: 9.00ms" "Max: 11.00ms" "----------------------------------------"
Testcase: Async function
Input: // async function const asyncFunction = async () => { await new Promise(resolve => setTimeout(resolve, 100)); return 'done'; }; // measure performance of the async function measurePerformance(asyncFunction, { name: 'Async Calculation', iterations: 5, warmup: true }); Output: "Performance Results for Async Calculation:" "----------------------------------------" "Type: Async" "Iterations: 5" "Average: 105.60ms" "Min: 104.00ms" "Max: 107.00ms" "----------------------------------------"
Compare performance of two or more functions in JavaScript
We can reuse the measurePerformance
function and create a comparePerformance
function that will take two or more functions and compare there performance.
async function comparePerformance(functions, options = {}) { const { logResults } = options; const results = []; for (const { fn, name } of functions) { const result = await measurePerformance(fn, { ...options, name }); results.push(result); } // sort results by average time results.sort((a, b) => a.average - b.average); if (logResults !== false) { console.log('\nPerformance Comparison:'); console.log('----------------------------------------'); results.forEach((result, index) => { console.log(`${index + 1}. ${result.name}:`); console.log(` Average: ${result.average.toFixed(2)}ms`); console.log(` Min: ${result.min.toFixed(2)}ms`); console.log(` Max: ${result.max.toFixed(2)}ms`); }); console.log('----------------------------------------\n'); } return results; }
Testcase
Input: // async function const asyncFunction = async () => { await new Promise(resolve => setTimeout(resolve, 100)); return 'done'; }; // normal function const syncFunction = () => { let sum = 0; for (let i = 0; i < 1000000; i++) { sum += i; } return sum; }; // compare two functions await comparePerformance([ { fn: syncFunction, name: 'Sync Calculation' }, { fn: asyncFunction, name: 'Async Operation' } ], { iterations: 5, warmup: true }); Output: "Performance Results for Sync Calculation:" "----------------------------------------" "Type: Sync" "Iterations: 5" "Average: 2.40ms" "Min: 2.00ms" "Max: 3.00ms" "----------------------------------------" "Performance Results for Async Operation:" "----------------------------------------" "Type: Async" "Iterations: 5" "Average: 104.40ms" "Min: 100.00ms" "Max: 113.00ms" "----------------------------------------" "Performance Comparison:" "----------------------------------------" "1. Sync Calculation:" " Average: 2.40ms" " Min: 2.00ms" " Max: 3.00ms" "2. Async Operation:" " Average: 104.40ms" " Min: 100.00ms" " Max: 113.00ms" "----------------------------------------"