为什么bitwise-xor(^)比Firefox中的不等于(!=)比较快?

时间:2015-01-13 12:16:28

标签: performance comparison bitwise-xor

我正在阅读其他网站(Computer Science - Can a Minimum Possible Efficiency be proven?)关于为最坏情况假设最小Big-O时间的文章。

其中一个答案用于解释比较二进制值(或类似值)所需时间的长度。

我对自己说:为什么不按位操作?

我在Javascript中制作了这个模拟代码:

console.time('^');
for(var i=0;i<1e5;i++)13^15;
console.timeEnd('^');

console.time('!=');
for(var i=0;i<1e5;i++)13!=15;
console.timeEnd('!=');

我真的很惊讶!

使用^(bitwise-xor)的循环几乎可以 3ms

这怎么可能?

为什么bitwise-xor(^)比不等于(!=)comparisson快?


其他可能相关的信息:

我已经在Windows 7 Home Premium x64上运行的Firefox 34.0.5上进行了测试。

我还在Opera 12.17(x64)和Chrome 39.0.2171.95上尝试了这个代码,行为几乎相似,使用^的代码更快80%的测试。


另一个惊喜:

在php中,运行这个:

$now=microtime(true);
for($i=0,$x=0;$i<1e6;$i++)$x+=13^15;
echo microtime(true)-$now,PHP_EOL;

$now=microtime(true);
for($i=0,$x=0;$i<1e6;$i++)$x+=13!=15;
echo microtime(true)-$now,PHP_EOL;

显示完全效果相同:^!=快。
使用$x+=!13^15;代替$x+=13^15;的时间更快70%。

我已在http://writecodeonline.com/php/上测试,它在linux x64上运行PHP 5.3。

此代码向用户@AlexK。提出以下评论的建议:

  

13 ^ 15是一个常数noop,也许它只是简单地优化了(尝试有效的x + = 13 ^ 15;)

1 个答案:

答案 0 :(得分:1)

你正在咆哮着错误的树木。

比如说,一个2GHz的CPU,^或!=可以在纳秒或其附近执行。执行1e6将需要1ms,而不是460ms。这告诉我两件事:

  1. for需要花费大量时间,
  2. JavaScript 已解释已编译
  3. 请注意,口译员不一定要花时间优化。一个非常好的优化器会将for($i=0,$x=0;$i<1e6;$i++)$x+=13^15;变为$x = 2000000。它显然没有那样做。好的,很难判断它是否已$x+=13^15变为$x+=2

    让我们看看另一件事。在机器级别,甚至在间隔级别$x+=13!=15都比$x+=13^15更复杂。两者都涉及$x+=,但13^15是单个操作,而13!=15(在此上下文中!)是两个操作 - 首先比较!=的13和15以获得真,然后将true转换为1.硬件级别有很多方法可以做到 - 大多数都涉及跳转,这是很昂贵的。还有其他技术涉及多个布尔/移位/等指令,只是为了避免跳转。

    也许13!=15速度较慢。但由于for循环的显着开销,你不知道多少。

    无论如何,这有关系吗?是否存在这两种操作可以互换的情况?您没有与可能相同的(13^15)!=0进行比较。