Pretty straightforward, but I just want to know which is faster.
I think simply multiplying a number by -1
is much faster than calling a predefined meth
I would suggest picking the method that more clearly shows your intention, rather than worrying about the performance. In this case, the performance gain of multiplying by -1 is probably minimal.
When you use Math.abs()
, it is very clear that you want a positive value. When you use * -1
it is not clear, and requires more investigation to determine if the input value is always negative.
Just the *-1
operation is probably faster, but keep in mind that the end result differs from the result for math.abs().
math.abs(-5)
and math.abs(5)
both return 5.
-5 * -1
returns 5 as well.
5 * -1
returns -5.
So unless you're absolutely sure that the number is negative to begin with, you have to do some tests, which cost more time. Might as well do math.abs().
But really, if the performance difference between abs() and *-1 matters in your JS, your probably have more serious issues.
I suppose it depends on the implementation, but Math.abs
could be as simple as:
function abs(x) {
return x < 0 ? x * -1 : x;
}
So, in theory, it just adds a quick test before multiplying.
But, yes, negating a negative sign is the sole purpose. The point is that a simple x * -1
is also counter-productive for positive values.
@olliej [comments]
True. Simple edit, though. ;)
function abs(x) {
return Number(x < 0 ? x * -1 : x);
}
Updated August, 2012:
I did some profiling with these implementations:
/* Test 1: */ b = Math.abs(a);
/* Test 2: */ b = abs(a); //local copy: abs = Math.abs;
/* Test 3: */ b = a < 0 ? a * -1 : a;
/* Test 4: */ b = a < 0 ? -a : a;
I got the following result on Windows 7. Values are normalized after the fastest result per browser to make it easier to compare which method is faster:
1:Math 2:abs 3:*-1 4:- 1.0= Version
Chrome 1.0 1.0 1.0 1.0 111ms 21.0.1180.75 m
Firefox 1.0 1.0 1.2 1.2 127ms 14.0.1
IE 1.4 1.0 1.1 1.0 185ms 9.0.8112
Opera 1.9 1.6 1.1 1.0 246ms 12.00
Safari 1.6 1.6 1.1 1.0 308ms 5.1.7
Conclusion:
When I did this test 3 years ago, -a was fastest, but now Math.abs(x) is faster in Firefox! In Chrome abs(a)
and -a
got the same time and it was only 3 ms difference to the slowest method when I tested it with 10 000 000 numbers.
My Recommendation: Use Math.abs(a). If you are in a tight loop and by profiling has found it to be too slow, you can use a local reference to the abs function:
var abs=Math.abs; //A local reference to the global Math.abs function
for (i=0;i<1234567890;++i) if ( abs( v[i] ) > 10) ++x;
A style question: Why use a * -1
instead of -a
?
Apart from that I agree that you should use abs()
if you don't know the sign of the number beforehand. I would not care for speed but for readability.