未定义参数的性能损失

我经常在函数中使用可选的参数,但是一些测试显示他们在firefox和safari(70-95%)中有巨大的性能影响。 奇怪的是,如果我传递未定义的字面值,那么就没有惩罚。 这里会发生什么? 我不会认为这是一个范围链问题,因为它们本身就是本地功能。 我是否会将undefined传入每个可选参数?

jsPerf:http://jsperf.com/function-undefined-args/2


对于这样的功能:

function threeArgs(x, y, z) {
  return x + y + z;
}

这就是这样调用的:

threeArgs(1, 2, 3);

优化器可以自由选择根本不产生任何代码。 确定没有副作用是相当容易的,因为函数只是引用其参数值并返回简单表达式的结果。 由于返回值被忽略,运行时没有任何理由做任何事情。

除此之外,如果代码是:

something += threeArgs(1, 2, 3);

优化器可能会决定生成大致等价于以下内容的代码:

something += 6;

为什么? 由于该调用是使用数字常量进行的,因此可以在代码生成时安全地折叠这些调用。 这可能是保守的,因为数字很奇怪,但在这里它们都是整数,所以它可以做到这一点。 即使它没有,它可以安全地内联功能:

something += 1 + 2 + 3;

然而,当缺少某个参数时,优化器可能会释放并产生实际的函数调用。 对于这样一个简单的函数,函数调用的开销很容易导致性能上的巨大差异。

通过在测试中使用变量而不是常量,并且通过实际使用函数的返回值,您可以“优化”优化器,避免跳过调用或预先计算结果,但无法避免内联。 我仍然认为你的结果是有趣的,因为这个原因:它暴露了这样一个事实,即(至今为止)这些优化器对函数被调用的方式很敏感。


我认为可以解释性能差异的是参数传递给函数对象的方式:通过arguments对象。 当不传递任何参数时,JS将首先扫描任何给定参数的参数对象,当这些arguments未定义时, arguments原型链将被扫描,一直到Object.prototype 。 如果这些都缺乏所需的属性,JS将返回undefined 。 然而,显式传递undefined,将其直接设置为arguments对象的属性:

function foo(arg)
{
    console.log(arguments.hasOwnProperty('0'));
}
foo();//false'
foo('bar');//true
foo(undefined);//true

我认为这就是明确传递undefined的原因往往会更快。

链接地址: http://www.djcxy.com/p/64159.html

上一篇: Performance penalty for undefined arguments

下一篇: Accessing local variable doesn't improve performance