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

时间:2009-01-14 04:22:38

标签: javascript performance

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

我认为只需将数字乘以-1比调用预定义方法快得多,前提是您确定该值为负数。

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

5 个答案:

答案 0 :(得分:70)

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;

我在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

<强>结论: 当我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;

答案 1 :(得分:24)

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

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

答案 2 :(得分:11)

我认为这取决于实现,但Math.abs可以简单如下:

function abs(x) {
    return x < 0 ? x * -1 : x;
}

因此,从理论上讲,它只是在乘法之前添加一个快速测试。

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


@olliej [评论]

真。但是,简单编辑。 ;)

function abs(x) {
    return Number(x < 0 ? x * -1 : x);
}

答案 3 :(得分:4)

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

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

-5 * -1也会返回5.

5 * -1返回-5。

因此,除非您完全确定该数字是否为负数,否则您必须进行一些测试,这会耗费更多时间。不妨做math.abs()。

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

答案 4 :(得分:2)

样式问题:为什么使用a * -1代替-a? 除此之外,如果您事先不知道号码的标志,我同意您应该使用abs()。我不关心速度,但是为了便于阅读。