哪个更快:Math.abs(值)或值*-1?

loc*_*ock 40 javascript performance

非常简单,但我只是想知道哪个更快.

我认为简单地乘以数字-1比调用预定义方法要快得多,前提是您确定该值为负数.

但如果是这样,那么abs()功能是什么?它是否只是为了确保返回的值始终是正值而不管值的符号?

som*_*ome 73

2012年8月更新:

我对这些实现进行了一些分析:

/* 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;
Run Code Online (Sandbox Code Playgroud)

我在Windows 7上得到了以下结果.在每个浏览器获得最快结果后,将值标准化,以便更轻松地比较哪种方法更快:

        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
Run Code Online (Sandbox Code Playgroud)

结论: 当我3年前做过这个测试时,-a是最快的,但现在Math.abs(x)在Firefox中更快!在Chrome中abs(a),并-a得到了相同的时间,当我10 000 000号测试它,它只有3毫秒的差异最慢的方法.

我的建议:使用Math.abs(a).如果你处于紧密循环中并且通过分析发现它太慢,你可以使用对abs函数的本地引用:

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;
Run Code Online (Sandbox Code Playgroud)


Bra*_*non 24

我建议选择更清楚地表明你的意图的方法,而不是担心性能.在这种情况下,乘以-1的性能增益可能是最小的.

当你使用时Math.abs(),很明显你想要一个正值.当您使用* -1它时,目前尚不清楚,需要进行更多调查以确定输入值是否始终为负值.

  • +1.优化的第一条规则:*"不要做"*.优化的第二条规则(仅限专家!):*"不要这样做......"*:-) (6认同)

Jon*_*ski 11

我想这取决于实现,但Math.abs可能很简单:

function abs(x) {
    return x < 0 ? x * -1 : x;
}
Run Code Online (Sandbox Code Playgroud)

所以,从理论上讲,它只是在乘法之前增加了一个快速测试.

但是,是的,否定负号只是唯一的目的.关键在于,简单x * -1对于正值也会适得其反.


@olliej [评论]

真正.但是,简单编辑.;)

function abs(x) {
    return Number(x < 0 ? x * -1 : x);
}
Run Code Online (Sandbox Code Playgroud)


Sie*_*tse 5

只是*-1操作可能更快,但请记住,最终结果math.abs() 的结果不同

math.abs(-5)并且math.abs(5)都返回 5。

-5 * -1 也返回 5。

5 * -1 返回-5。

因此,除非您完全确定该数字一开始为负数,否则您必须进行一些测试,这会花费更多时间。也可以做 math.abs()。

但实际上,如果 abs() 和 *-1 之间的性能差异在您的 JS 中很重要,那么您可能会遇到更严重的问题。