浏览 11141 次
锁定老帖子 主题:eval与function的性能比较
精华帖 (1) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-09-11
日前,看到一位朋友在eval json串的,采用了
var a=new Function("return "+json); a();
的方式 。
想着人家为什么不用eval 于是就做了一个它们之间的 性能测试 <head> <title>代理测试</title> <script type="text/javascript"> //var aa="{aa:'xx'}"; var aa="{name:'cola',item:[{age:11},{age:22},{age:23},{age:23}]}"; var now=new Date().getTime(); for(var i=0;i<1000;i++){ eval("("+aa+")"); } var now1=new Date().getTime(); alert(now1-now); var now2=new Date().getTime(); for(var i=0;i<1000;i++){ var fn=new Function("return"+aa); fn(); } var now3=new Date().getTime(); alert(now3-now2); </script> </head>
结果发现在IE中eval是110ms,而fuction是172ms 在FF2中,eval是由1906ms,而fuctnion 187ms 可以看出 FF还是慢于IE6.但是eval在FF是出奇地慢。
可不可以改进一下eval呢?
var morik={}; morik.eval=function(s){ if(navigator.userAgent.toLowerCase().indexOf("msie") > -1) return eval(s); else{ var aa=new Function( "return"+s); return aa.apply(this);
}
};
本想采用 var _e=window.eval; var eval=fucntion(s){...}, 但是改不了作用域,上下文变量通过函数的能达到一定的效果。 便是this却得不到指向运行eval方法的函数指向的。
因为想兼容以前的代码,没有采用eval.apply(this,[])的方法。 有什么好的方法?
prk 08- 09-11 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-09-11
一直在用new Function.
eval关于作用域浏览器见不一致. 还是new Function.对作用域便于控制. 建议彻底放弃eval. |
|
返回顶楼 | |
发表时间:2008-09-11
不过eval在IE中的速度还是蛮快的。
|
|
返回顶楼 | |
发表时间:2008-09-11
new Function 额外还有指定scope的方便,——选这个了
|
|
返回顶楼 | |
发表时间:2008-09-19
有谁研究过为何FF的eval会这么慢吗?是不是工作机制的原因?
|
|
返回顶楼 | |
发表时间:2009-03-10
seaprince 写道 有谁研究过为何FF的eval会这么慢吗?是不是工作机制的原因?
期待。。。 |
|
返回顶楼 | |
发表时间:2009-05-08
学习了,这个确实很严重。。。
|
|
返回顶楼 | |
发表时间:2009-05-08
最后修改:2009-05-08
唔…… 在 ff3 测了下,eval 比 ff2 快很多,但还是比不上 Function。
var benchmark = function(f) { var begin = new Date().getTime() for(i = 0; i < 1000; i++) f(); alert(new Date().getTime() - begin) } var aa="{name:'cola', item:[{age:11}, {age:22}, {age:23}, {age:23}]}" benchmark(function(){ eval("(" + aa + ")") }) //469 benchmark(function(){ new Function("return (" + aa + ")")() }) //174 //改写的 eval eval = function(s){ new Function("return (" + aa + ")")() } benchmark(function(){ eval(aa) }) //226 |
|
返回顶楼 | |
发表时间:2009-05-08
最后修改:2009-05-08
这个问题,可以参看这篇文章:
http://weblogs.asp.net/yuanjian/archive/2009/03/22/json-performance-comparison-of-eval-new-function-and-json.aspx 原因探讨:
修改后的测试代码及结果:(ff3.0.10, 禁用了 firebug) var benchmark = function(f) { var begin = new Date().getTime() for(i = 0; i < 3000; i++) f(i); //注: 循环次数越小,eval 优势越大。循环次数很大时,两者就很接近了。大概还有其它优化机制在作用。 alert(new Date().getTime() - begin) } var a1 = "{name:'cola', item:[{age:11}, {age:22}, {age:23}, {age:" var a2 = "}]}" benchmark(function(i){ eval("(" + a1 + i + a2 + ")") }) // 157 ms benchmark(function(i){ new Function("return (" + a1 + i + a2 + ")")() }) // 186 ms 结论: 没必要用 Function 代替 eval 。 |
|
返回顶楼 | |
发表时间:2009-05-09
使用动态生成<script>标签并且设置其text为json的方式,在firefox下可以比eval快2.4倍左右,在IE下没有明显变化。这种方式在JQuery3中被采用了。IE8的JSON.parser据说性能提高不少,我测试时报告错误,后来才搞清是在IE quirk模式下无法使用。
|
|
返回顶楼 | |