Firefox JavaScript算术表现奇怪

Fri*_*izi 12 javascript performance firefox arithmetic-expressions

请在firefox上运行此测试.

http://jsperf.com/static-arithmetic

你会如何解释结果?

这个

b = a + 5*5;
b = a + 6/2;
b = a + 7+1;
Run Code Online (Sandbox Code Playgroud)

执行速度比

b = a + 25;
b = a + 3;
b = a + 8;
Run Code Online (Sandbox Code Playgroud)

为什么?

Bor*_*sky 1

Firefox 版本 4-8 有两种不同的 JIT:Tracemonkey (tracejit) 和 JaegerMonkey (methodjit)。TraceMonkey 在简单的数字代码上要好得多;JaegerMonkey 在各种分支代码上表现得更好。

有一个启发式方法用于决定使用哪个 JIT。它考虑了一系列因素,其中大部分与这里无关,但对于此测试用例而言,重要的是循环体中的算术操作越多,使用 TraceMonkey 的可能性就越大。

javascript.options.tracejit.content您可以通过更改和的值来测试这一点,javascript.options.methodjit.content以强制代码在一个或另一个 JIT 下运行,然后查看这对性能有何影响。

看起来常量折叠并不能挽救测试用例的相同行为,因为 Spidermonkey 无法常量折叠a + 7 + 1 = (a + 7) + 1to a + 8,因为它不知道a是什么(例如,"" + 7 + 1 == "71"while "" + 8 == "8")。如果你这样写,a + (7 + 1)那么你会突然得到另一个 JIT 在此代码上运行。

所有这些都证明了从微基准推断到实际代码的危险。;)

哦,Firefox 9 只有一个 JIT(JaegerMonkey 基于 Brian Hackett 的类型推断工作进行了优化,使其在此类算术代码上也能快速运行)。