Javascript Math.ceil(Math.abs()) optimization

前端 未结 6 972
清酒与你
清酒与你 2020-12-10 17:17

I\'m using Math.ceil( Math.abs( x ) ) inside a loop.

Can anyone realize any optimization for this operation? (Bitwise or what?)

You are welcom

相关标签:
6条回答
  • 2020-12-10 17:54

    parseInt(Math.abs(x)) + 1 is faster by about 30% on Firefox according to jsperf

    As the argument is always positive, the branches in Math.ceil() are unnecessary.

    0 讨论(0)
  • 2020-12-10 17:54

    Two fastest ways to do calculations (giving almost the same speed in modern browsers):

    function f (n) {
       return (~~n) + 1;
    }
    
    // or 
    
    function f1 (n) {
       return (n | 0) + 1;
    }
    
    // some tests, ~~ operator seems to work identicaly on numbers:
    
    ( 3.3 | 0 ) === 3;   
    ( 3.8 | 0 ) === 3;   
    ( -3.3 | 0 ) === -3; 
    ( -3.8 | 0 ) === -3;  
    

    unlike Math.floor(-3.3) == Math.floor(-3.8) == -4

    0 讨论(0)
  • 2020-12-10 17:56

    Javascript isn't a compiled language like C, so bitwise operations that can work wonders in such languages, aren't so great in JS because numbers are stored as 64 bit floating points. Take a look at this SO post.

    Even then, what you write in JS will get transformed to native code somehow by underlying browser and it might be faster or slower, depending on implementation.

    Since Math.ceil and Math.abs are built in; I'd guess they're heavily optimized, so I doubt you'll be able to get better performance by doing some trickery of your own.

    Bottom line: three things stand in your way of doing it faster:

    1. number representation in JS
    2. fact that it's an interpreted language
    3. functions you use are "native", so they should be fast enough on their own
    0 讨论(0)
  • 2020-12-10 18:03

    Math.abs doesn't get simpler according to webkit JavaScriptCore

    case MathObjectImp::Abs:
    result = ( arg < 0 || arg == -0) ? (-arg) : arg;
    

    However ceil uses C's ceil function

     case MathObjectImp::Ceil:
        result = ::ceil(arg);
    

    so testing on JSpref http://jsperf.com/math-ceil-vs-bitwise bitwise is faster
    testing @orangedog's answer http://jsperf.com/math-ceil-vs-bitwise/2 Math.ceil is faster

    So I guess your best choice is:

    var n = Math.abs(x);
    var f = (n << 0),
    f = f == n ? f : f + 1;
    
    0 讨论(0)
  • 2020-12-10 18:06

    x < 0 ? Math.ceil(-x) : Math.ceil(x) produces a 40% speedup in Firefox 3.6 (little difference in the others) while remaining relatively readable.

    Here is the jsPerf page. Ignore the "some bitwise operators" label; the expression above doesn't use any.

    0 讨论(0)
  • 2020-12-10 18:08

    Here's another one, which doesn't need to do any lookup:

    ((x >= 0 ? x : -x) + 0.5) >> 0
    
    0 讨论(0)
提交回复
热议问题