eval的兩組效能測試資料

來源:互聯網
上載者:User

@老趙 的一個微博“ 由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的影響》 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.