【发布时间】:2015-03-23 05:24:34
【问题描述】:
众所周知,在 JavaScript 中不当使用 arguments 可能会导致函数无法优化(请参阅 here 和 here by the end):
function notOptimisable (a, b) {
// Optimising compiler says: Nope.
var args = [].slice.call(arguments)
}
但是,到目前为止,没有任何消息来源能够解释为什么这会阻止优化发生。
这更令人难以置信,因为我所要做的就是
function optimisable (a, b) {
// Optimising compiler says: I can do this!
var args = new Array(arguments.length)
, i = 0
// Copy the arguments into an actual array, very carefully...
for(i; i < args.length; ++i)
args[i] = arguments[i]
}
瞧——我有一个 arguments 的副本,它是一个实际的数组,并且可以优化函数:
node --trace_opt --trace_deopt script.js # Exerpt below
[marking 0x24ba2c0bf0f1 <JS Function notoptimisable (SharedFunctionInfo 0x26b62a724859)> for recompilation, reason: small function, ICs with typeinfo: 3/3 (100%), generic ICs: 0/3 (0%)]
[disabled optimization for 0x26b62a724859 <SharedFunctionInfo notoptimisable>, reason: Bad value context for arguments value]
[failed to optimize notoptimisable: Bad value context for arguments value]
[marking 0x24ba2d0041b1 <JS Function optimisable (SharedFunctionInfo 0x26b62a7247b1)> for recompilation, reason: small function, ICs with typeinfo: 7/7 (100%), generic ICs: 0/7 (0%)]
[optimizing 0x24ba2d0041b1 <JS Function optimisable (SharedFunctionInfo 0x26b62a7247b1)> - took 0.039, 0.164, 0.051 ms]
因此,我问你:
为什么?
- 哪些技术挑战阻碍了优化?
- 为什么 v8 引擎不能像第二个代码示例显示的那样简单地返回一个标准的参数数组并优化函数?
- 另外,为什么
arguments从语言设计的角度来看只是一个“类似数组”的对象(即它有数字键,但它不是 Array 的后代)并且它是否在某种程度上起到了作用优化过程?
【问题讨论】:
-
我认为问题在于将
arguments传递给其他函数,这需要各种奇怪的东西(阅读参数对象的规范)来阻止优化。因为 V8 无法知道被调用的函数 (slice) 没有使用这些奇怪的东西。 -
@bergi 如何将速度提高一倍:jsperf.com/array-with-and-without-length/5(剧透,放开
switch)
标签: javascript optimization v8