两天前,当我发现jsperf.com收集了许多javascript性能测试时,我浏览了几个测试。
其中一项测试是this,将Math.min(a,b)
与a<b?a:b
进行比较。当我在Google Chrome上运行此测试时,发现a<b?a:b
比Math.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
。
当我在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
慢得多。
摘要:
a<b?a:b
比Math.min(a,b)
快。Math.min(a,b)
比a<b?a:b
快。Math.min(a,b)
的速度Google谷歌Chrome浏览器上a<b?a:b
的速度和Firefox上a<b?a:b
的速度≒谷歌Chrome浏览器上Math.min(a,b)
的速度“ Firefox很慢“或”Firefox很快“不能成为理由。有没有理由(如何)这种情况发生?
答案 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的事情
有关更深入的信息,请查看http://qfox.nl/ecma/366以获取示例实现。
P.S。我知道这个问题已经过时了,但如果我去过去,我认为可以节省一些时间。