Javascript 为什么未执行的语句会减慢我的函数?
我创建了四个不同的函数,如下所示:Javascript 为什么未执行的语句会减慢我的函数?,javascript,performance,Javascript,Performance,我创建了四个不同的函数,如下所示: var normal = function() { return; }; var control = function() { return; alert("Hello, world!"); }; var withArguments = function() { return; arguments; }; var withEval = function() { return; eval(""); };
var normal = function() {
return;
};
var control = function() {
return;
alert("Hello, world!");
};
var withArguments = function() {
return;
arguments;
};
var withEval = function() {
return;
eval("");
};
因为他们都什么都不做,马上就回来了,我希望他们都有同样的速度。但是,之后,我发现normal
和control
执行得差不多,但是withArguments
和withEval
执行得慢得多
为什么这些未执行的语句会对性能产生影响?由于它们从未执行过,它们怎么可能产生任何效果呢?简言之,在函数内部调用
eval
,并且能够访问参数
数组都会在函数调用期间使用额外的设置。如果已知既不执行参数
也不执行eval
,则可以跳过此额外设置
编译器不会尝试预测是否实际访问参数
数组,或者是否实际调用eval
,它只检查函数中是否存在这些参数
参数
在运行时调用使用参数
对象的变量函数比调用不使用参数
对象的“普通”函数的成本更高
声明参数
对象时绑定执行环境所需的额外步骤如下。创建参数
对象是一个有点昂贵的15步过程。基本上,参数
必须用传入的参数填充,并且必须创建.caller
和.callee
属性
该标准规定,除非名为arguments
的函数中已经声明了参数、变量或函数,否则应在函数进入其执行上下文时创建arguments
对象
出于优化的目的,大多数浏览器不会实际创建arguments对象,除非函数在某个地方实际使用它(即使在返回之后)。这就是为什么在引用参数时会看到性能下降,即使包含它的行从未执行过
eval
输入eval
code,需要创建一个特殊的执行上下文。基本上,它必须将调用函数的执行上下文的所有属性绑定到eval
上下文
如果在一个函数中调用了多个eval
s,那么它们基本上都将执行相同的过程两次。为了优化,如果浏览器检测到函数中存在eval
(即使在返回之后),它会预先填充每个eval
都可以使用的新执行上下文,这样就不需要多次重新创建
请注意,这些优化依赖于浏览器,并且不是标准所要求的,因此某些浏览器可能不会实际执行所描述的优化,或者可能会执行不同的操作。不同的浏览器/javascript引擎如何处理您的测试脚本?我不确定这会有什么不同,但是你运行过函数返回值的测试吗?+1是最好的答案。FWIW,我在IE10上运行了测试,withArguments()
测试的运行速度与normal()
和control()
一样快;所以我假设IE10会在这个实例中延迟安装,直到实际需要为止。非常感谢!调用eval()
的方法也将在全局范围内执行它。