eval的两组性能测试数据

@老赵 的一个微博“ 由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的影响》

(0)

相关推荐

  • eval的两组性能测试数据

    @老赵 的一个微博" 由eval生成的代码效率真的很差吗? http://t.cn/zWTUBEo 内含人身攻击,不喜勿入." 引发了最近对eval火爆的讨论,教主 @Franky 和 灰大 @otakustay 也给了精彩的数据分析. 刚好之前也做过类似的测试,我也跟风凑个热闹,提供两组数据供大家参考. 更新1: 感谢灰大 @otakustay 的指导,为排除eval('')调用本身对结果的影响,增加一组新数据A3, B3.并对旧的全部数据重测. 更新2: 感谢莫大 @貘吃馍香 的强

  • asp两组字符串数据比较合并相同数据

    a1="sp2=20;sp1=34;" a2="sp3=2;sp2=3;sp1=4;" 两组字符串数据,将字符串中相同的数据值相加后得到新的一组数据 即"sp3=2;sp2=23;sp1=38" (p.s 一个简单的应用:商品二原有数量20件,商品一原有数量34件,新进货或者新出售了商品二3件,商品一4件等类型模拟情况下计算出进货量,销售量和库存量,小型的进销存系统可采用这样的方法) 那么如何实现两组字符串数据比较合并相同数据? 第一,将两组字符

  • python中将两组数据放在一起按照某一固定顺序shuffle的实例

    有的时候需要将两组数据,比如特征和标签放在一起随机打乱, 但是又想记录这种打乱的顺序,那么该怎么做呢?下面是一个很好的方法: b = [1, 2,3, 4, 5,6 , 7,8 ,9] a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h','i'] c = list(zip(a, b)) print(c) random.Random(100).shuffle(c) print(c) a, b = zip(*c) print(a) print(b) 输出: [('

  • python不使用for计算两组、多个矩形两两间的iou方式

    解决问题: 不使用for计算两组.多个矩形两两间的iou 使用numpy广播的方法,在python程序中并不建议使用for语句,python中的for语句耗时较多,如果使用numpy广播的思想将会提速不少. 代码: def calc_iou(bbox1, bbox2): if not isinstance(bbox1, np.ndarray): bbox1 = np.array(bbox1) if not isinstance(bbox2, np.ndarray): bbox2 = np.arr

  • 基于python实现计算两组数据P值

    我们在做A/B试验评估的时候需要借助p_value,这篇文章记录如何利用python计算两组数据的显著性. 一.代码 # TTest.py # -*- coding: utf-8 -*- ''' # Created on 2020-05-20 20:36 # TTest.py # @author: huiwenhua ''' ## Import the packages import numpy as np from scipy import stats def get_p_value(arrA

  • 利用vue对比两组数据差异的可视化组件详解

    目录 需求: 大概要点: 根据刚才的要点可以建立一下组件的props: 组件的基本样式也很简单: 完事了,最后贴一下完整代码: 使用示例: 效果预览: 扩展功能TODO: 总结 如题,朋友有个这样的需求,感觉挺常见,发出来给大家参考一下 需求: 用el-table展示两组数据,有差异的单元格显示红色,新增的显示整行绿色 大概要点: 需要一个数据组,里面包含两组需要对比的数据 需要一个唯一的key,用来确定某一行的数据是否在其他数据中存在(是否是新增 接受一个表格列的配置,用于渲染表格,同时对比差

  • R语言两组变量特征相关关系热图绘制画法

    目录 准备数据 简单热图 只对列进行聚类 将相关系数显示在图上 在图上加上显著性标记 准备数据 两组变量的数据可以像下面这样处理,分别保存在两个csv文件中. > # 导入数据及数据预处理 > setwd("D:/weixin/") > rows <- read.csv("rows.csv") > cols <- read.csv("cols.csv") > str(rows) 'data.frame':

  • sysbench对mysql压力测试的详细教程

    前言 在对网站整体性能进行benchmark时,可以使用多种工具,比如大名鼎鼎的ab(Apache bench),http_load等工具.这里我们不关注他们的使用,如果你想了解,可以自行在网上找到答案. 重点来说MySQL的基准测试如何进行,也有很多种工具来供我们选择,比如mysqlslap.sysbench.Super Smack等,其中mysqlslap的使用MySQL官网给出了介绍,Super Smack是服务器压力测试强有力的工具,那么sysbench便是我们进行MySQL基准测试的很

  • 整理AngularJS框架使用过程当中的一些性能优化要点

    1. 简介 无论你正在编写一个旧的应用程序还是在一个大型应用中采用AngularJS,性能是一个重要的方面.了解是什么原因导致AngularJS应用程序慢下来非常重要,要知道,在开发过程中做出权衡是很重要的.本文将介绍一些AngularJS比较常见的性能问题,以及优化的建议. 2. 性能测试工具 本文采用jsPerf http://jsperf.com/ 性能测试的基准. 3. 软件性能 评价软件性能有两个基本的因素: 首先是算法的时间复杂度.一个简单的例子就是线性搜索和二分检索有着非常显著的性

  • PostgreSQL教程(十):性能提升技巧

    一.使用EXPLAIN: PostgreSQL为每个查询都生成一个查询规划,因为选择正确的查询路径对性能的影响是极为关键的.PostgreSQL本身已经包含了一个规划器用于寻找最优规划,我们可以通过使用EXPLAIN命令来查看规划器为每个查询生成的查询规划.     PostgreSQL中生成的查询规划是由1到n个规划节点构成的规划树,其中最底层的节点为表扫描节点,用于从数据表中返回检索出的数据行.然而,不同的扫描节点类型代表着不同的表访问模式,如:顺序扫描.索引扫描,以及位图索引扫描等.如果查

随机推荐