eval的两组性能测试数据


Posted in Javascript onAugust 17, 2012

@老赵 的一个微博“ 由eval生成的代码效率真的很差吗? http://t.cn/zWTUBEo 内含人身攻击,不喜勿入。”
引发了最近对eval火爆的讨论,教主 @Franky 和 灰大 @otakustay 也给了精彩的数据分析。
刚好之前也做过类似的测试,我也跟风凑个热闹,提供两组数据供大家参考。

更新1: 感谢灰大 @otakustay 的指导,为排除eval('')调用本身对结果的影响,增加一组新数据A3, B3。并对旧的全部数据重测。
更新2: 感谢莫大 @貘吃馍香 的强力拍砖,增加了1). A4, B4;A5,B5的eval覆盖后的测试数据; 2). A6,B6 eval别名;3). A7,B7 eval.call。

测试环境:
a. 机器:Intel(R) Corei7-2720 2.2Ghz (4核心8线程)、内存8Gb
b. OS:Windows 7 Enterprise SP1 64-bit
c. 浏览器:
b.1 Google Chrome 21.0.1180.79 m
b.2 Firefox 14.0.1
b.3 IE9.0.8112.16421
d. 测试方法
d.1 每个用例测试5次,耗时取最小值。
d.2 测试过程中没有开启Firebug或Chrome Console,开启这些工具会使时间倍增,很难在有效时间内得到该用例结果

用例A1:
我们在内联函数中调用空的eval("")

!function() { 
var a = 1, 
b = 2, 
c = true; 
function func() { 
var d = 2; 
e = !c; 
eval(""); 
} 
for (var i = 0; i < 2999999; i++) { 
func(i, i + 1, i + 2); 
} 
}();

用例A2:
注释掉内联函数中的eval("")
!function() { 
var a = 1, 
b = 2, 
c = true; 
function func() { 
var d = 2; 
e = !c; 
//eval(""); 
} 
for (var i = 0; i < 2999999; i++) { 
func(i, i + 1, i + 2); 
} 
}();

用例A3:
为排除eval("")调用本身产生的影响,我们在外层函数中调用eval("")
!function() { 
var a = 1, 
b = 2, 
c = true; 
function func() { 
var d = 2; 
e = !c; 
} 
for (var i = 0; i < 2999999; i++) { 
eval(""); 
func(i, i + 1, i + 2); 
} 
}();

用例A4:
将eval()函数覆盖成普通的空函数
function eval(){} 
!function() { 
var a = 1, 
b = 2, 
c = true; 
function func() { 
var d = 2; 
e = !c; 
eval(""); 
} 
for (var i = 0; i < 2999999; i++) { 
func(i, i + 1, i + 2); 
} 
}();

用例A5:

同样是函数调用,不是eval而且另一个空函数f

function f(){} 
!function() { 
var a = 1, 
b = 2, 
c = true; 
function func() { 
var d = 2; 
e = !c; 
f(""); 
} 
for (var i = 0; i < 2999999; i++) { 
func(i, i + 1, i + 2); 
} 
}();

用例A6:
将eval赋给另一个变量f,然后调用f
var f = eval; 
!function() { 
var a = 1, 
b = 2, 
c = true; 
function func() { 
var d = 2; 
e = !c; 
f(""); 
} 
for (var i = 0; i < 2999999; i++) { 
func(i, i + 1, i + 2); 
} 
}();

用例A7:

使用eval.call的方式去调用

!function() { 
var a = 1, 
b = 2, 
c = true; 
function func() { 
var d = 2; 
e = !c; 
eval.call(null, ''); 
} 
for (var i = 0; i < 2999999; i++) { 
func(i, i + 1, i + 2); 
} 
}();

A组测试结果: 

A1 A2 A3 A4 A5 A6 A7 A1 : A2 A1 : A3 A1 : A4 A4 : A5
Chrome 1612ms 8ms 1244ms 897ms 7ms 718ms 680ms 201.5 1.3 1.8 128.1
Firefox 2468ms 69ms 732ms 2928ms 134ms 5033ms 4984ms 35.8 3.4 0.8 21.9
IE 1207ms 23ms 233ms 1147ms 37ms 148ms 224ms 52.5 5.2 1.0 31.0
用例B1:
for (var i = 0; i < 2999999; i++) { 
!function() { 
var a = 1, 
b = 2, 
c = true; 
!function () { 
var d = 2; 
e = !c; 
eval(""); 
}(); 
}(); 
}

用例B2:
for (var i = 0; i < 2999999; i++) { 
!function() { 
var a = 1, 
b = 2, 
c = true; 
!function () { 
var d = 2; 
e = !c; 
//eval(""); 
}(); 
}(); 
}

用例B3:
for (var i = 0; i < 2999999; i++) { 
!function() { 
var a = 1, 
b = 2, 
c = true; 
!function () { 
var d = 2; 
e = !c; 
}(); 
}(); 
eval(""); 
}

用例B4:
var eval = function(){} 
for (var i = 0; i < 2999999; i++) { 
!function() { 
var a = 1, 
b = 2, 
c = true; 
!function () { 
var d = 2; 
e = !c; 
eval(""); 
}(); 
}(); 
}

用例B5:
var f = function(){} 
for (var i = 0; i < 2999999; i++) { 
!function() { 
var a = 1, 
b = 2, 
c = true; 
!function () { 
var d = 2; 
e = !c; 
f(""); 
}(); 
}(); 
}

用例B6:
var f = eval; 
for (var i = 0; i < 2999999; i++) { 
!function() { 
var a = 1, 
b = 2, 
c = true; 
!function () { 
var d = 2; 
e = !c; 
f(""); 
}(); 
}(); 
}

用例B7:
for (var i = 0; i < 2999999; i++) { 
!function() { 
var a = 1, 
b = 2, 
c = true; 
!function () { 
var d = 2; 
e = !c; 
eval.call(null, ''); 
}(); 
}(); 
}

B组测试结果:
B1 B2 B3 B4 B5 B6 B7 B1 : B3 B1 : B2 B1 : B4 B4 : B5
Chrome 1569ms 134ms 1093ms 1022ms 173ms 830ms 916ms 11.7 1.4 1.5 5.9
Firefox 5334ms 1017ms 5503ms 5280ms 1171ms 6797ms 6883ms 5.2 1.0 1.0 4.5
IE 3933ms 560ms 680ms 4118ms 583ms 745ms 854ms 7.0 5.8 1.0 111.3

结论(仅限于文中的CASE):

1.  eval本身的重复调用非常耗时,即使是空的eval("");

2.  eval对内联函数执行效率有所影响,依具体环境、代码有所不同;

3.  我们可以看到无论哪种浏览器,无论是A组还是B组,2 和 5速度较佳。说明例中内联函数的eval无论以何种方式调用(即使eval被空函数覆盖)仍会对运行效率造成较大影响。推断是(黑盒推断,非权威,很可能是臆测)内联函数中只要发现eval,哪怕这个eval是被覆盖的空函数,在Scope Variables中都将会把所有的外部定义的变量等内容初始化到当前的Scope中。类似的,eval会对内联函数在运行时JS引擎的优化功能产生较大影响,降低执行效率。

4. 说点题外话,虽然没用IE10,而是IE9,在对eval的处理上,表现非常的优异。IE一直被开发人员诟病,但它的飞速成长也是值得肯定的,本例就是很好的一项证明。 

更详细的原因剖析下列文章描述已十分详细,不再累述。欢迎拍砖:)尤其是莫大... 

 @老赵          的 《由eval生成的代码效率真的很差吗?》 
 @Franky      的  《Eval科普》 
 @otakustay  的 《浅谈Eval的影响》 

Javascript 相关文章推荐
求解开jscript.encode代码的asp函数
Feb 28 Javascript
Jquery乱码的一次解决过程 图解教程
Feb 20 Javascript
javascript克隆对象深度介绍
Nov 20 Javascript
基于JQuery的列表拖动排序实现代码
Oct 01 Javascript
遍历DOM对象内的元素属性示例代码
Feb 08 Javascript
js获取指定日期周数以及星期几的小例子
Jun 27 Javascript
JS实现n秒后自动跳转的两种方法
Nov 30 Javascript
Angularjs的启动过程分析
Jul 18 Javascript
java遇到微信小程序 &quot;支付验证签名失败&quot; 问题解决
Dec 22 Javascript
JavaScript监听一个DOM元素大小变化
Apr 26 Javascript
JavaScript实现alert弹框效果
Nov 19 Javascript
四十九个javascript小知识实用技巧
Nov 20 Javascript
javascript五图轮播切换实用版
Aug 17 #Javascript
JS左右无缝滚动(一般方法+面向对象方法)
Aug 17 #Javascript
javascript基础知识大全 便于大家学习,也便于我自己查看
Aug 17 #Javascript
jquery插件制作 手风琴Panel效果实现
Aug 17 #Javascript
jquery插件制作 提示框插件实现代码
Aug 17 #Javascript
jquery插件制作 自增长输入框实现代码
Aug 17 #jQuery
jquery插件制作 表单验证实现代码
Aug 17 #Javascript
You might like
php中拷贝构造函数、赋值运算符重载
2012/07/25 PHP
去掉destoon资讯内容页keywords关键字自带的文章标题的方法
2014/08/21 PHP
php比较相似字符串的方法
2015/06/05 PHP
PHP创建多级目录的两种方法
2016/10/28 PHP
解决Laravel无法使用COOKIE和SESSION的问题
2019/10/16 PHP
强制设为首页代码
2006/06/19 Javascript
JQuery.Ajax之错误调试帮助信息介绍
2013/07/04 Javascript
父元素与子iframe相互获取变量和元素对象的具体实现
2013/10/15 Javascript
用javascript删除当前行,添加行(示例代码)
2013/11/25 Javascript
深入理解JSON数据源格式
2014/01/10 Javascript
jquery计算出left和top,让一个div水平垂直居中的简单实例
2016/07/13 Javascript
JS实现图文并茂的tab选项卡效果示例【附demo源码下载】
2016/09/21 Javascript
vue中使用heatmapjs的示例代码(结合百度地图)
2018/09/05 Javascript
Vue插件之滑动验证码用法详解
2020/04/05 Javascript
vue移动端写的拖拽功能示例代码
2020/09/09 Javascript
Python通过PIL获取图片主要颜色并和颜色库进行对比的方法
2015/03/19 Python
Django中对数据查询结果进行排序的方法
2015/07/17 Python
浅析Python中的for 循环
2016/06/09 Python
浅谈python字典多键值及重复键值的使用
2016/11/04 Python
Python实现字符串逆序输出功能示例
2017/06/24 Python
使用Eclipse如何开发python脚本
2018/04/11 Python
python 给DataFrame增加index行名和columns列名的实现方法
2018/06/08 Python
python assert的用处示例详解
2019/04/01 Python
django用户登录验证的完整示例代码
2019/07/21 Python
手写一个python迭代器过程详解
2019/08/27 Python
pygame实现烟雨蒙蒙下彩虹雨
2019/11/11 Python
I.T集团香港官方商城:ITeSHOP.com Hong Kong
2019/02/15 全球购物
夜不归宿检讨书
2014/02/25 职场文书
质量月活动策划方案
2014/03/10 职场文书
2014年客房部工作总结
2014/11/22 职场文书
承诺书模板大全
2015/05/04 职场文书
百日宴上的祝酒词
2015/08/10 职场文书
三好学生评选事迹材料(2016精选版)
2016/02/25 职场文书
个人房屋租赁合同(标准范本)
2019/09/16 职场文书
《传颂之物 虚伪的假面》BD发售宣传CM公开
2022/04/04 日漫
Java GUI编程菜单组件实例详解
2022/04/07 Java/Android