Javascript Math.ceil(Math.abs())优化

Javascript Math.ceil(Math.abs())优化,javascript,performance,optimization,bit-manipulation,Javascript,Performance,Optimization,Bit Manipulation,我在循环中使用Math.ceil(Math.abs(x)) 有人能实现此操作的任何优化吗?(按位还是什么?) 欢迎您使用benchmark atJavascript不像C那样是一种编译语言,因此在这种语言中能够发挥奇效的位操作在JS中并不是很好,因为数字存储为64位浮点。看看这个 即使这样,您在JS中编写的代码也会被底层浏览器以某种方式转换为本机代码,并且可能会更快或更慢,具体取决于实现 因为内置了Math.ceil和Math.abs;我猜它们是经过了大量优化的,所以我怀疑您是否能够通过自己的一

我在循环中使用
Math.ceil(Math.abs(x))

有人能实现此操作的任何优化吗?(按位还是什么?)


欢迎您使用benchmark at

Javascript不像C那样是一种编译语言,因此在这种语言中能够发挥奇效的位操作在JS中并不是很好,因为数字存储为64位浮点。看看这个

即使这样,您在JS中编写的代码也会被底层浏览器以某种方式转换为本机代码,并且可能会更快或更慢,具体取决于实现

因为内置了
Math.ceil
Math.abs
;我猜它们是经过了大量优化的,所以我怀疑您是否能够通过自己的一些技巧获得更好的性能

一句话:有三件事阻碍你更快地完成任务:

  • JS中的数字表示
  • 事实上,这是一种解释性语言
  • 您使用的函数是“本机的”,因此它们本身应该足够快
  • 根据jsperf的数据,在Firefox上,
    parseInt(Math.abs(x))+1
    的速度要快30%左右


    由于参数始终为正,因此Math.ceil()中的分支是不必要的。

    这里有另一个分支,它不需要进行任何查找:

    ((x >= 0 ? x : -x) + 0.5) >> 0
    

    根据webkit JavaScriptCore,Math.abs并没有变得更简单

    case MathObjectImp::Abs:
    result = ( arg < 0 || arg == -0) ? (-arg) : arg;
    
    因此,在JSpref上进行测试 按位更快
    测试@orangedog的答案Math.ceil更快

    所以我想你最好的选择是:

    var n = Math.abs(x);
    var f = (n << 0),
    f = f == n ? f : f + 1;
    
    var n=Math.abs(x);
    var f=(n
    x<0?Math.ceil(-x):Math.ceil(x)
    在Firefox 3.6中产生了40%的加速(与其他版本几乎没有差异),同时保持了相对可读性


    以下是。忽略“某些位运算符”标签;上面的表达式不使用任何运算符。

    两种最快的计算方法(在现代浏览器中提供几乎相同的速度):


    Math.floor(-3.3)=Math.floor(-3.8)不同==-4

    ps:我需要的是操作的返回值,而不是条件,我担心它不会比你做的更简单。我已经将测试值改为负浮点,而不是整数,因此代码实际上必须做些什么。从WebKit源代码中可以看到,JavaScript方法
    Math.abs()和 >数学> CELL()>使用C++ CMASUCTION函数。我真的不认为你能优化它。你确定这是个问题吗?你能发布你正在使用的代码吗?@ Crozin:开销是查找和调用函数(动态调度),你可以通过使用操作符(静态调度)来摆脱这些函数。它可能会更快,也可能不会更快,但它也是错误的-任何具有零值分数分量的数字都会错误地比ceil’d值大1。啊,这一点很好。检查这一点,毫不奇怪,会使它再次变慢。您忘记了调度开销-使用运算符而不是方法很可能会加快代码的速度,尽管如此值得注意的是,在JS中,数字都是双倍的,所有JS引擎实际上都在可能的情况下以整数存储值,因此位运算符仍然很快,因为当数字已经是整数时,不需要进行转换。我认为在这种情况下,做一些位运算比上限函数快。大拇指朝上,您在Webkit中做了大量的研究源代码!这里的舍入是
    Math.round
    而不是
    Math.ceil
    f1(1);//2。
    这些函数不遵循
    Math.ceil
    行为。也许你应该接受排名靠前的答案,而不是你自己的答案。
    var n = Math.abs(x);
    var f = (n << 0),
    f = f == n ? f : f + 1;
    
    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;