使用`新Function`和性能问题

问题描述:

我加载通过AJAX脚本文件,并运行它的内容我这样做:使用`新Function`和性能问题

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

然而,根据MDN:

Function使用Function构造函数创建的对象在创建函数时被解析。这比声明一个函数并在你的代码中调用它的效率要低,因为用函数声明声明的函数和其余的代码一起被解析。

我真的不太明白。如果声明了一个函数,它仍然需要从文件的字符串格式中解析出来,那么为什么要运行一个通过new Function加载的字符串会降低效率?

这对我来说真的是一件好奇的事情。我可以理解为什么它会在循环中变坏(不得不重新解析相同的字符串),但对于这样的事情我不认为有任何问题,是吗?

+2

它的解析几乎就像eval一样,这已知很慢。我*假设*它应该快一点,因为不需要连接范围链。 – bfavaretto 2013-05-08 01:36:30

+0

不要通过AJAX发送函数,发送数据。在_.js_或'

+0

@PaulS。这适用于预加载器脚本。 – 2013-05-08 01:41:44

认为的MDN文档指的是这样的:

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

至于反对:

function f() { return 5; } 

前者版本是效率较低,因为它首先创建一个实际的String对象(“return 5”)in JavaScript然后解析该字符串以创建一个Function对象。后者解析没有中间字符串的代码。

这就是说,在你的情况下,因为你动态加载JavaScript代码,我不认为真的有任何解决它的方法。

+0

+1给你和Ryan,但你会因为你的榜样而变得简单一些。 – 2013-05-08 01:42:40

我觉得他们说的是,如果你使用的功能构造函数在你的代码是这样的:

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

函数体被解析两次:第一次作为一个字符串被加载代码的时候,第二次是在运行时构造函数。在你的情况下,你正在解析代码后从ajax响应中创建函数,所以真的是一个完全不同的交易。

我不知道该MDN文章的作者意图是什么,但这里有一个解释。

许多现代JS解释器使用优化编译器来生成本机代码。

例如,"JavaScriptCore, the WebKit JS implementation"说:三种形式之间

在这种情况下有分层编译:初始解析和编译产生的字节码,可以与方法JIT进行优化,能够由被优化DFG JIT。但实际上,在大多数平台上不包括解释器,所有代码都通过JIT方法运行。

编译器对编译代码的优化越完善,它可以执行的优化越多,因此函数的优化程度越高。例如,如果你知道每一个函数的引用都被用来立即用一个字符串作为它的唯一参数来调用它,因为它是在一个严格的函数体中定义的,那么你可能可以避免为它分配一个函数对象并在其主体中执行某些优化。

当您调用new Function时,优化编译器不会获取执行这些优化和其他优化所需的上下文。

+0

好吧,那么这将如何适用于我的情况:使用'new Function'的代码是预加载器,并且正在分析的代码是我正在处理的游戏的实际脚本。 – 2013-05-08 01:51:34

+1

@Kolink,它适用于您的情况吗?你有没有进行基准测试,看它是否有任何性能影响?当数据很容易收集时,不要在没有数据的情况下做出性能决定。只要尝试一下你所拥有的东西,以及使用'