Why are unexecuted statements slowing down my functions?

Solution 1:

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.