为什么Firefox和其他浏览器在计算哪个数字更大时表现相反?

时间:2011-09-07 10:35:57

标签: javascript performance firefox google-chrome

两天前,当我发现jsperf.com收集了许多javascript性能测试时,我浏览了几个测试。

其中一项测试是this,将Math.min(a,b)a<b?a:b进行比较。当我在Google Chrome上运行此测试时,发现a<b?a:bMath.min(a,b)快得多(在Chrome 14上,第一个是53,661,381 ops/s,第二个是419,830,711 ops/s) 。其他网络浏览器也有类似的结果。

然而,在Firefox上,结果却相反。 Math.min(a,b)a<b?a:b快得多!第一个是374,219,869 ops/s,第二个是Firefox 6上的79,490,749 ops/s

enter image description here

当我在Facebook上发布此消息时,有人说“由于Firefox是开源项目,开发人员优化Math.min,但谷歌Chrome没有,因为谷歌Chrome只是Chromium的修改”,但是(旁边)上述声明并不完全正确)这没有任何意义,因为这并不能解释Google Chrome的a<b?a:b和Firefox的Math.min(a,b)以相似的速度执行的原因,以及Google Chrome的Math.min(a,b)和Firefox的a<b?a:b执行速度相同,因为如果Firefox比谷歌Chrome更快,那么谷歌浏览器的Math.min(a,b)应该比Firefox的a<b?a:b慢得多。

摘要:

  1. 在其他浏览器上,a<b?a:bMath.min(a,b)快。
  2. 但是,在Firefox上,Math.min(a,b)a<b?a:b快。
  3. 由于Firefox上Math.min(a,b)的速度Google谷歌Chrome浏览器上a<b?a:b的速度和Firefox上a<b?a:b的速度≒谷歌Chrome浏览器上Math.min(a,b)的速度“ Firefox很慢“或”Firefox很快“不能成为理由。
  4. 有没有理由(如何)这种情况发生?

2 个答案:

答案 0 :(得分:8)

这里有一些事情发生。

首先,在Firefox 6中有两种不同的JIT编译器:TraceMonkey和JaegerMonkey。哪一个用于给定的代码取决于一些启发式;这些启发式方法倾向于使用TraceMonkey来处理带有函数调用的代码。碰巧的是,对于简单的代码,TraceMonkey几乎总是比JaegerMonkey更快;特别是这里提供的两个代码片段就是这种情况。

在这个特定的基准测试中,Math.min代码路径使用Tracemonkey编译,因为它是一个函数调用。使用JaegerMonkey编译三元运算符代码路径。

您可以通过转到about:config,将jit放入过滤器字段并禁用TraceMonkey(列表中的tracejit)和JaegerMonkey(methodjit)中的一个或两个来试验此操作。如果你这样做,你会发现在这个特定的基准测试中,每个编译器的三元运算符比Math.min快,因此与其他浏览器相比,你看到的反转只是使用的一个函数。不同的编译器。

现在为什么Math.min通常比三元运算符慢...首先它需要做更多的工作;如果仔细测试,它返回的答案与三元运算符不同。其次,它通常作为函数调用实现,这是大多数开销来自的地方(尽管TraceMonkey实际上在生成的代码中明确地内联它,这就是为什么两个片段的性能在TraceMonkey中没有那么不同)。 / p>

答案 1 :(得分:1)

在我阅读Dev.Opera上的Efficient Javascript并运行一些不同的基准测试后,我遇到了同样的问题。我认为那部分有点误导。有很多东西会降低Math.min的速度,但没有一个能真正解释Google Chrome与Firefox或IE9的性能。

我认为减缓Math.min的事情

  • 使用arguments对象
  • 必须检查是否有任何值是NaN
  • 如果没有给出args,则返回Infinity等其他内容,+ 0&gt; -0

有关更深入的信息,请查看http://qfox.nl/ecma/366以获取示例实现。

P.S。我知道这个问题已经过时了,但如果我去过去,我认为可以节省一些时间。