I was working on optimising a javascript maths function and wanted to compare the performance of different versions of the code. Initially I had some difficulty because I was approaching it incorrectly so I wanted to make a note for future reference.
First mistake – only using a small number of runs. I was comparing the two different functions with a very small iteration amount. This was leading to weird results where each iteration would get faster even though it was actually the same code running. I think this was related to some compiler optimisation or something. Anyway, after reading JavaScript Compiler Optimization Techniques, I changed to a very large number of runs. This made the results much more consistent.
Second mistake – using perf_hooks incorrectly. From the same blog I also found out the nice way to use perf_hooks to measure the performance:`
import { performance, PerformanceObserver } from 'perf_hooks';
let iterations = 1_000_000;
performance.mark('start');
while (iterations--) {
StableMath._calcOutGivenIn(
poolPairDataBigInt.amp,
poolPairDataBigInt.balances,
poolPairDataBigInt.tokenIndexIn,
poolPairDataBigInt.tokenIndexOut,
amt,
poolPairDataBigInt.fee
);
}
performance.mark('end');
iterations = 1_000_000;
performance.mark('startSecond');
const invariant = StableMath._calculateInvariant(
poolPairDataBigInt.amp,
poolPairDataBigInt.balances,
true
);
while (iterations--) {
StableMath._calcOutGivenInNoInv(
poolPairDataBigInt.amp,
poolPairDataBigInt.balances,
poolPairDataBigInt.tokenIndexIn,
poolPairDataBigInt.tokenIndexOut,
amt,
poolPairDataBigInt.fee,
invariant
);
}
performance.mark('endSecond');
const obs = new PerformanceObserver((list, observer) => {
console.log(list.getEntries()); // [0]);
performance.clearMarks();
observer.disconnect();
});
obs.observe({ entryTypes: ['measure'] });
performance.measure('NoOptimisation', 'start', 'end');
performance.measure('WithOptimisation', 'startSecond', 'endSecond');
Which results in an output like:
[
PerformanceMeasure {
name: 'NoOptimisation',
entryType: 'measure',
startTime: 2369.287365913391,
duration: 35891.85489702225,
detail: null
},
PerformanceMeasure {
name: 'WithOptimisation',
entryType: 'measure',
startTime: 38261.19673395157,
duration: 18529.005373954773,
detail: null
}
]
As well as having a nice output it also shows my optimisation worked pretty nicely!