未定义参数的性能损失
我经常在函数中使用可选的参数,但是一些测试显示他们在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