Which is faster: Math.abs(value) or value * -1 ?

Viewed 35586

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 method, provided that you are sure that value is negative.

But if that's the case then what is the abs() function for? Is it simply for making sure that the value returned would always be positive regardless of value's sign?

5 Answers

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;

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.

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);
}

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.

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.

Related