I know Math.abs() and Math.round() are very different functions, but I assumed they would have a relatively similar efficiency.
console.time('round');
for (var i = 0; i < 100000; i++) {
var a = Math.random() - 0.5;
Math.round(a);
}
console.timeEnd('round');
console.time('abs');
for (var i = 0; i < 100000; i++) {
var a = Math.random() - 0.5;
Math.abs(a);
}
console.timeEnd('abs');
The previous produced these results: round: 136.435ms abs: 4777.983ms
Can anyone explain the radical difference in the timing?
EDIT: When I run the snippit here i get MUCH faster results. Around 2 and 3 ms. Why on earth would it get such radically higher times in a different tab?
Thanks!
I am not sure you are measuring what you think you are
The random can really mess things up by cache missing. Also you are substracting by 0.5
which is also FPU operation that is quite more complex then abs
itself. I am not JAVA coder but I hope Math.abs(x)
is floating point and not integer operation (In C/C++ abs
is integer and fabs
is floating point). I would create array with random numbers set prior to your loops and then use that in your loops
abs
abs
is just sign bit test + non zero mantissa test. if implementation contains brunch then that can seriously slow thing down. Luckily float/double abs implementation does not need any brunch you just mask out the sign bit (as mantissa is not in 2'os complement for standard IEEE 754 formats).
round
round
is test if MSB of fractional part of mantissa is 1 and if yes then is integer increment applied. so the target is bit shifted to integer and MSB fraction bit is extracted. if implementation contains brunch then that can seriously slow thing down but usually faster is extract the MSB fraction bit to Carry flag and use adc
. Still this needs more work than abs
and so it should be slower.
so why the results are as are?
Is your implementation/platform using FPU or software emulation? On FPU the complexity of both operations is almost the same (because the overhead of communication with FPU is usually bigger then such operation itself). On emulation it depends on implementation of the operations and target platform architecture (pipelines,cache control,...)
my guesses are:
abs
loop is worse with Cache missesabs
implementation is not that much optimized as it could beround
is optimized by compiler, sometimes round(x)=floor(a+0.5)
and you have a-=0.5;
before and as you do not use a
for anything else there is a possibility compiler ignores the floor(random-0.5+0.5)
and use directly floor(random)
[notes]
The times you measured 132ms and 4.7sec are way too big on what HW did you try this? The times from your edit are much more reasonable for common PC HW and code interpreter these days. Did you measure this more then 1 times ?
If you are trying this in brownser then it could be slowed down by anything in its background (like snipped from different page or still downloading something ...) Also OS can pause the execution but not that much