Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of `new Function` and performance issues

Tags:

javascript

I'm loading a script file via AJAX, and to run its content I'm doing this:

new Function('someargument',xhr.responseText)(somevalue);

However, according to MDN:

Function objects created with the Function constructor are parsed when the function is created. This is less efficient than declaring a function and calling it within your code, because functions declared with the function statement are parsed with the rest of the code.

I really don't quite get it. If a function is declared, it still has to be parsed from the string format of the file, so why would running a loaded string through new Function be any less efficient?

This is really more of a curiosity thing for me. I can understand why it would be bad in a loop (having to re-parse the same string), but for something like this I don't think there's any issue, is there?

like image 287
Niet the Dark Absol Avatar asked May 08 '13 01:05

Niet the Dark Absol


3 Answers

I think what they are saying is that if you use the function constructor in your code like this:

new Function('bar', 'console.log(bar);'));

The function body is parsed twice: the first time as a string when the code is loaded, and the second time when the function is constructed at runtime. In your case, you are creating the function from an ajax response after the code has been parsed, so really its a whole different deal.

like image 185
Ryan Lynch Avatar answered Oct 05 '22 16:10

Ryan Lynch


I think the MDN docs are referring to something like this:

var f = new Function("return 5;");

As opposed to:

function f() { return 5; }

The former version is less efficient because it first creates an actual String object ("return 5") in JavaScript and then parses that string to create a Function object. The latter parses the code without an intermediate string.

That said, in your case since you're loading the JavaScript code dynamically I don't think there's really any getting around it.

like image 20
Dan Tao Avatar answered Oct 05 '22 15:10

Dan Tao


I don't know what the author of that MDN article intended, but here is one interpretation.

Many modern JS interpreters use an optimizing compiler to produce native code.

For example, "JavaScriptCore, the WebKit JS implementation" says:

In that case there is tiered compilation between the three forms: initial parsing and compilation produces bytecode, that can be optimized with the method JIT, that can be optimized by the DFG JIT. In practice, though, on most platforms the interpreter is not included, so that all code runs through the method JIT.

The more complete the picture an optimizing compiler has of the code it's compiling, the more optimizations it can perform, so the more highly optimized the function can be. For example, if you know that every reference to a function is used to call it immediately with a string as its sole argument because it is defined in a strict function body, then you might be able to avoid allocating a function object for it at all and perform certain optimizations in its body.

When you call new Function, the optimizing compiler does not get the context necessary to do those and other optimizations.

like image 34
Mike Samuel Avatar answered Oct 05 '22 14:10

Mike Samuel