繁体   English   中英

为什么Javascript Eval比较慢,什么时候不应该

[英]Why Javascript Eval is slower, when it shouldn't be

所以我试图创建我自己的JS框架只是为了我自己的乐趣(然后可能转换成有用的)我大部分时间专注于动态生成JS(因为JS具有更高级别作为中间语言是坏主意,IMO)

我遇到了一个麻烦。 我试图做以下

var f = null;
var converted = "f = function(){ <do something here>";
for(var x in list)
 converted+=list[x];
converted+="};";
eval(converted);

所以这几乎将构造函数写入f,我以后可以执行。

但是这里有一个问题 - 它运行得比我刚刚在文件中完全编写f代码要慢,这很奇怪。 让我解释为什么它对我来说很奇怪:当你每次运行eval时,Chrome预编译器(或任何浏览器预编译器 - chrome是我的目标)都无法缓存 - 编译代码,因为它预计会随着每个代码而改变跑。

但是,当您将其保存到某个功能时,它会创建一个新的VM机器文件,因为在保存该功能的代码后,您无法更改它。 那么,为什么,当我这样做时,它比正常执行运行得慢? 我的意思是代码执行不止一次。 为什么这应该重要?

PS:我上面显示的方法,每次进行评估的速度更快。 所以我不明白为什么秒表会显示中间时间,再次忽略前1-10次通话

PPS:测试用例: http//jsperf.com/evaluated-function-vs-real-function/2

eval基本上是不可优化的,因为编译器不知道它在做什么。 即使将其保存到函数中,编译器也必须选择退出很多优化,因为以某种方式更改代码可能会破坏eval函数。

这就是为什么通常,当你需要做一个eval时,你可以在另一个函数中执行:这样,编译器可以确保你没有修改eval局部作用域,并且优化得更好。

JS VMs真的很多关于启发式方法。 他们试图猜测你想做什么,并针对一般情况进行优化。 eval (或new Function )阻止他们做很多事情。

Function.new 可能会快一点,因为编译器会知道它不会尝试修改范围。


还来了 请注意, eval可能与您习惯的方式略有不同。 例如, eval('a')(0, eval)('a') 不一样

我会用它来证明这一点

window.a = 5;
void function () {
  var a = 1;
  eval('a = 2');
  console.log(a);
  console.log(window.a);
}();

这将打印1然后打印5

window.a = 5;
void function () {
  var a = 1;
  (0,eval)('a = 2'); // <- this line has changed
  console.log(a);
  console.log(window.a);
}();

然而,这将打印1然后打印2

您还可以阅读: 全球评估,有哪些选择

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM