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

前端 未结 5 1795
天涯浪人
天涯浪人 2020-12-25 11:24

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

相关标签:
5条回答
  • 2020-12-25 11:59

    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.

    0 讨论(0)
  • 2020-12-25 12:01

    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.

    0 讨论(0)
  • 2020-12-25 12:02

    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);
    }
    
    0 讨论(0)
  • 2020-12-25 12:05

    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;
    
    0 讨论(0)
  • 2020-12-25 12:08

    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.

    0 讨论(0)
提交回复
热议问题