JavaScript - test algorithm performance
In this article, we would like to show how to test algorithms' performance in JavaScript.
Usually, when we compare algorithms that execution times are short, we repeat computations multiple times to get precise results. The number of repeats is selected empirically. The source code that is not an algorithm part shouldn't be measured.
Main concept:
// ONLINE-RUNNER:browser;
const test = (repeats, description, func) => {
const t1 = performance.now(); // OR: const t1 = Date.now();
for (let i = 0; i < repeats; ++i) {
func();
}
const t2 = performance.now(); // OR: const t2 = Date.now();
const dt = t2 - t1;
console.log(`${description}: total time is ${dt} ms`);
};
// Usage example:
const repeats = 100000; // set number of repeats depending on complexity of tested cases
test(repeats, 'case 1', () => { /* source code case 1 */ });
test(repeats, 'case 2', () => { /* source code case 2 */ });
test(repeats, 'case 3', () => { /* source code case 3 */ });
// add more cases here ...
Hint: presented concept describes only a simple way how to test performance - in practice tests made by benchmarks are more complex.
Practical example
In the below example we compare algorithms that computes Fibonacci sequence values.
In the test, we made 100000 repeats on Fibonacci algorithms using Ryzen 9 x5900 processor and V8 JS Engine (Google Chome v110) under Windows 11.
Test result:
Case 1: Iterative algorithm: total time is 65.39999999990687 ms
Case 2: Binet's formula: total time is 1.1000000000931323 ms
Conclusion: iterative algorithm is ~35 times slower in the tested cases.
Test source code:
// ONLINE-RUNNER:browser;
const test = (repeats, description, func) => {
const t1 = performance.now(); // OR: const t1 = Date.now();
for (let i = 0; i < repeats; ++i) {
func();
}
const t2 = performance.now(); // OR: const t2 = Date.now();
const dt = t2 - t1;
console.log(`${description}: total time is ${dt} ms`);
};
// Performance tests:
const repeats = 100000; // set number of repeats depending on complexity of tested cases
{
const fibonacci = (number) => {
if (number < 1) return 0;
if (number < 2) return 1;
return fibonacci(number - 2) + fibonacci(number - 1);
};
test(
repeats,
'Case 1: Iterative algorithm',
() => {
for (let i = 1; i < 10; ++i) {
fibonacci(i);
}
}
);
}
{
const fibonacci = (number) => {
var a = Math.pow(1 + 2.23606797749979, number);
var b = Math.pow(1 - 2.23606797749979, number);
var c = 2.23606797749979 * Math.pow(2, number);
return Math.round((a - b) / c);
};
test(
repeats,
'Case 2: Binet\'s formula',
() => {
for (let i = 1; i < 10; ++i) {
fibonacci(i);
}
}
);
}