【发布时间】:2015-01-06 00:44:45
【问题描述】:
我做了a jsPerf test 来查看在 JavaScript 中的函数中使用参数或局部变量之间是否存在性能差异。
在 Firefox 34 中,几乎没有区别。但是,在 Chrome 39 中,编译器似乎造成了很大的伤害。查看这些结果:
谁能解释为什么会这样?
【问题讨论】:
-
仅作记录,在 IE 11 中的结果相同。
标签: javascript google-chrome v8
我做了a jsPerf test 来查看在 JavaScript 中的函数中使用参数或局部变量之间是否存在性能差异。
在 Firefox 34 中,几乎没有区别。但是,在 Chrome 39 中,编译器似乎造成了很大的伤害。查看这些结果:
谁能解释为什么会这样?
【问题讨论】:
标签: javascript google-chrome v8
首先,对于尝试测量参数与局部变量性能行为的基准测试,您在每种情况下都做了太多 - 您一次又一次地分配闭包,从对象分配对象字面意思,您使用 for-in 循环。所有这些操作都比局部变量访问要更多昂贵。他们的成本包含并隐藏了任何小的成本变量访问。
现在您看到的异常是由于 V8 没有创建包含文字的闭包的快速路径:有 FastNewClosureStub 但它仅在闭包中没有文字时使用[1]。与第二种情况相比,这使得第一种情况下的闭包分配成本更高 - 您会在分数中看到这一点,因为闭包分配是您的基准测试中相当重要的部分(它为每个 op 分配一个闭包)。
如果您将文字创建[2]“隐藏”到单独的函数中,您将看到异常消失。注意:这种隐藏不再使基准测试具有代表性:它仍然不测量您想要测量的内容。
总体而言,试图在基准测试中捕获变量访问的性能特征非常困难,因为即使在非优化(基线)编译器生成的代码中,这些通常也是最快和最小的操作之一。在最常见的情况下,当没有捕获变量并且范围不包含 with、eval 或 arguments 对象时 - 参数和局部变量访问之间没有区别,它们都编译成单个内存负载。
[2]http://jsperf.com/variable-vs-variable-passed-as-an-argument-to-a-self-in/3
【讨论】: