优化参数有什么用?

Rob*_*ann 9 javascript optimization v8

众所周知,arguments在JavaScript 中使用不当可能会导致函数无法优化(请参见此处此处):

function notOptimisable (a, b) {
  // Optimising compiler says: Nope.
  var args = [].slice.call(arguments)
}
Run Code Online (Sandbox Code Playgroud)

但是,到目前为止,没有一个消息来源能够解释为什么这会阻止优化的发生.

这更令人难以置信,因为我所要做的就是

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]
}
Run Code Online (Sandbox Code Playgroud)

和voilá - 我有一个副本,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]
Run Code Online (Sandbox Code Playgroud)

因此,我问你:

为什么?

  • 哪些技术挑战阻碍了优化的发生?
  • 为什么v8引擎不能简单地返回一个标准的参数数组,就像第二个代码示例显示和优化函数一样?
  • 对于额外的点,为什么arguments从语言设计的角度来看,它是唯一一个"类似数组"的对象(即它有数字键,但它不是数组的后代)并且它在某种程度上在优化过程中起作用?

Vya*_*rov 6

没有不可克服的技术挑战.这只是在Crankshaft中实现arguments对象时做出的快捷决策:仅支持可以轻松避免参数对象实现的情况.

即使Crankshaft支持参数​​对象的实现,结果代码仍然比不分配参数对象的代码.

这只是一个问题,即在10分钟内支持最快的案例,而在10天内支持更慢但更通用的案例.(10分钟/ 10天是虚数,我只是想传达实现复杂性的规模差异).

如果想要支持参数对象实现(并且可能泄漏)的情况,则需要考虑参数对象和参数之间的别名 - 这会改变如何为这些变量构造SSA表单.由于类似的原因,这也使内联复杂化.

一个更通用的参数对象方法应该基于转义分析/分配下沉传递 - 但Crankshaft在实现时没有类似的东西,它仍然需要至少支持一些参数操作的快速路径.