为什么未执行的语句会减慢我的功能? [英] Why are unexecuted statements slowing down my functions?

查看:54
本文介绍了为什么未执行的语句会减慢我的功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了四个不同的函数,如下所示:

var normal = function() {返回;};var 控制 = 函数(){返回;alert("你好,世界!");};var withArguments = function() {返回;论据;};var withEval = function() {返回;评估(");};

由于它们都什么都不做并立即返回,因此我希望它们都具有相同的速度.但是,在 在 jsPerf 上测试 之后,我发现 normalcontrol 的执行大致相同,但 withArgumentswithEval 的执行速度要慢得多.

为什么这些未执行的语句会对性能产生任何影响?既然它们从来没有被执行过,它们怎么可能有任何效果?

解决方案

简而言之,在函数内部调用 eval 并且能够访问 arguments 数组都使用函数调用期间的额外设置.如果已知 argumentseval 都不会被执行,则可以跳过这个额外的设置.

编译器不会尝试预测 arguments 数组是否会被实际访问或 eval 是否会被实际调用,它只检查它们是否存在在函数中.

参数

在运行时调用使用 arguments 对象的可变参数函数比不使用 arguments 对象的普通"函数更昂贵.>

声明arguments对象时绑定执行环境所需的额外步骤是在 ECMA-262 标准的 §10.6 中指定.创建 arguments 对象是一个有点昂贵的 15 步过程.基本上,arguments 必须用传入的参数填充,并且必须创建 .caller.callee 属性.>

标准规定,arguments 对象应该在函数进入其执行上下文时创建,除非在名为 arguments 的函数内部已经声明了一个参数、变量或函数代码>.

出于优化的目的,大多数浏览器实际上不会创建参数对象,除非函数在某处实际使用它(即使在 return 之后).这就是为什么在引用 arguments 时会看到性能下降,即使包含它的行从未被执行.

eval

输入 eval 代码,如 ECMA §10.4.2 中指定的 -262 标准,需要创建一个特殊的执行上下文.基本上,它必须将调用函数的执行上下文的所有属性绑定到 eval 上下文.

如果在一个函数中调用了多个 eval ,它们基本上都会执行两次相同的过程.为了优化,如果浏览器检测到函数中有 eval(即使在 return 之后),它会预先填充这个新的执行上下文,每个 eval 可以使用,这样就不需要多次重新创建.

<小时>

请注意,这些优化取决于浏览器,并非标准所要求的,因此某些浏览器实际上可能不会执行所描述的优化,或者它们的处理方式可能有所不同.

I have created four different functions, like this:

var normal = function() {
    return;
};
var control = function() {
    return;
    alert("Hello, world!");
};
var withArguments = function() {
    return;
    arguments;
};
var withEval = function() {
    return;
    eval("");
};

Since they all just do nothing and immediately return, I would expect all of them to have the same speed. But, after testing it on jsPerf, I find that normal and control execute about the same, but withArguments and withEval execute much more slowly.

Why would these unexecuted statements have any performance impact? Since they're never executed, how is it possible for them to have any effect?

解决方案

In short, calling eval inside of a function and being able to access the arguments array both use extra set-up during function invocation. If it is known that neither arguments nor eval will be executed, this extra set-up can be skipped.

The compiler does not attempt to predict whether or not the arguments array will actually be accessed or whether eval will actually be called, it only checks whether or not they exist in the function.

arguments

It is more expensive during runtime to invoke a variadic function that uses the arguments object than a "normal" function that doesn't use the arguments object.

The extra steps required to bind the execution environment when the arguments object is declared are specified in §10.6 of the ECMA-262 standard. Creating the arguments object is a somewhat expensive 15-step process. Basically, arguments has to be populated with the passed-in arguments, and the .caller and .callee properties have to be created.

The standard says that the arguments object should be created when a function enters its execution context, unless there is already a parameter, variable, or function declared inside the function named arguments.

For purposes of optimization, most browsers do not actually create the arguments object unless the function actually uses it somewhere (even after a return). This is why you see a performance hit when arguments is referenced, even when lines containing it are never executed.

eval

Entering eval code, as specified in §10.4.2 of the ECMA-262 standard, requires creating a special execution context. Basically, it has to bind all the properties of the calling function's execution context to the eval context.

If there are multiple evals called in one function, they will basically both be doing the same process twice. For optimization, if browsers detect that there is an eval in the function (even after a return), it pre-populates this new execution context that every eval can use, so that it doesn't need to be recreated multiple times.


Note that these optimizations are browser dependent and not required by the standard, so some browsers might not actually perform the optimizations described, or they might do things differently.

这篇关于为什么未执行的语句会减慢我的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆