欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入探究JavaScript中for循環(huán)的效率問(wèn)題及相關(guān)優(yōu)化

 更新時(shí)間:2016年03月13日 10:59:56   投稿:goldensun  
這篇文章主要介紹了JavaScript中for循環(huán)的效率問(wèn)題及相關(guān)優(yōu)化,文中談到了Underscore.js庫(kù)及循環(huán)在各個(gè)瀏覽器js解釋器下的表現(xiàn),需要的朋友可以參考下

Underscore.js庫(kù)

你一天(一周)內(nèi)寫(xiě)了多少個(gè)循環(huán)了?

var i;
for(i = 0; i < someArray.length; i++) {
 var someThing = someArray[i];
 doSomeWorkOn(someThing);
}

這當(dāng)然無(wú)害,但這種寫(xiě)法非常丑而且奇怪,這也不是真正需要抱怨的。但這種寫(xiě)法太平庸了。

var i,
 j;
for(i = 0; i < someArray.length; i++) {
 var someThing = someArray[i];
 for(j = 0; j < someThing.stuff.length; j++) {
   doSomeWorkOn(someThing.stuff[j]);
 }
}

你在擴(kuò)展糟糕的代碼,在你拋出一大堆if前,你已經(jīng)精神錯(cuò)亂了。
我在兩年里沒(méi)有寫(xiě)一個(gè)循環(huán)(loop)。
“你在說(shuō)什么?”
這是真的,一個(gè)冷笑話。其實(shí)不是一個(gè)都沒(méi)有(好吧,我確實(shí)寫(xiě)了幾個(gè)),因?yàn)槲也粚?xiě)循環(huán)(loops),我的代碼更容易理解。
怎么做的呢?

_.each(someArray, function(someThing) {
 doSomeWorkOn(someThing);
})

或者更好一點(diǎn):

_.each(someArray, doSomeWorkOn);

這就是underscorejs所做到的。干凈,簡(jiǎn)單,易讀,短,沒(méi)有中間變量,沒(méi)有成堆的分號(hào),簡(jiǎn)單非常優(yōu)雅。
這是另外一些例子。

var i,
 result = [];
for(i = 0; i < someArray.length; i++) {
 var someThing = someArray[i];
 // 打到這,我已經(jīng)手疼了
 if(someThing.isAwesome === true) {
   result.push(someArray[i]);
 }
}

同樣,一個(gè)使用循環(huán)浪費(fèi)時(shí)間的典型用例。即便這些網(wǎng)站是宣傳禁煙和素食主義的,看到這些代碼我也感到義憤??纯春?jiǎn)單的寫(xiě)法。

var result = _.filter(someArray, function(someThing) {
 return someThing.isAwesome === true;
})

像underscore中的filter(過(guò)濾)的名字那樣,隨手寫(xiě)的3行代碼就可以給你一個(gè)新的數(shù)組(array)。
或者你想把這些數(shù)組轉(zhuǎn)換成另外一種形式?

var result = _.map(someArray, function(someThing) {
 return trasformTheThing(someThing);
})

上面三個(gè)例子在日常生活中已經(jīng)夠用了,但這些功能還不足矣讓underscore放到臺(tái)面上。

var grandTotal = 0,
 somePercentage = 1.07,
 severalNumbers = [33, 54, 42],
 i; // don't forget to hoist those indices;
for(i = 0; i < severalNumbers.length; i++) {
 var aNumber = severalNumbers[i];
 grandTotal += aNumber * somePercentage;
}

underscore版本

var somePercentage = 1.07,
 severalNumbers = [33, 54, 42],
 grandTotal;
grandTotal = _.reduce(severalNumbers, function(runningTotal, aNumber) {
 return runningTotal + (aNumber * somePercentage);
}, 0)

這個(gè)剛開(kāi)始看上去可能有點(diǎn)怪,我查了下關(guān)于reduce的文檔,知道了它的存在。因?yàn)槲揖芙^使用循環(huán),所以它是我的首選。上面這些東西僅僅是入門(mén),underscorejs庫(kù)還有一大堆牛B的功能。

30天不使用循環(huán)的挑戰(zhàn)。

在一下一個(gè)30天里,不要使用任何循環(huán),如果你看到一堆討厭和粗糙的東西,用each或者map將他們替換掉。再用一點(diǎn)reducing。

你需要注意到,Underscore是通往函數(shù)式編程的。一種看得見(jiàn),看不見(jiàn)的方式。一條很好的途徑。


OurJS注*目前現(xiàn)代瀏覽器已經(jīng)支持each, filter, map, reduce方法,但underscore庫(kù)可以實(shí)現(xiàn)對(duì)舊版IE的兼容,下面是使用ES5原生方法寫(xiě)的例子:

[3,4,5,3,3].forEach(function(obj){
  console.log(obj);
});

[1,2,3,4,5].filter(function(obj){
  return obj < 3
});

[9,8,5,2,3,4,5].map(function(obj){
  return obj + 2;
});

[1,2,3,4,5].reduce(function(pre, cur, idx, arr) {
  console.log(idx);  //4 個(gè)循環(huán): 2-5
  return pre + cur;
});  //15

//sort方法同樣很有用
[9,8,5,2,3,4,5].sort(function(obj1, obj2){
  return obj1 - obj2;
});

for in與for loop

有人提出for in的效率要比f(wàn)or loop(循環(huán))的效率低非常多?,F(xiàn)在我們測(cè)試一下在不同瀏覽器中使用for in, for loop和forEach在處理大數(shù)組時(shí)的效率究竟如何。

目前絕大部分開(kāi)源軟件都會(huì)在for loop中緩存數(shù)組長(zhǎng)度,因?yàn)槠胀ㄓ^點(diǎn)認(rèn)為某些瀏覽器Array.length每次都會(huì)重新計(jì)算數(shù)組長(zhǎng)度,因此通常用臨時(shí)變量來(lái)事先存儲(chǔ)數(shù)組長(zhǎng)度,如:

for (var idx = 0, len = testArray.length; idx < len; idx++) {
 //do sth.
}

我們也會(huì)測(cè)試一下緩存與不緩存時(shí)的性能差異。

同時(shí)在每個(gè)測(cè)試循環(huán)中添加求和運(yùn)算,來(lái)表明其不是空循環(huán)。

for (var idx = 0, len = testArray.length; idx < len; idx++) {
 //do sth.
}

我們也會(huì)測(cè)試一下緩存與不緩存時(shí)的性能差異。

同時(shí)在每個(gè)測(cè)試循環(huán)中添加求和運(yùn)算,來(lái)表明其不是空循環(huán)。

測(cè)試代碼如下,點(diǎn)擊運(yùn)行即可查看
HTML 代碼

<h4 id="browser"></h4>
<table id="results" class="table"></table>

JavaScript 代碼

function () {

 //準(zhǔn)備測(cè)試數(shù)據(jù), 有200萬(wàn)條數(shù)據(jù)的大數(shù)組
 var testArray = []
  , testObject = {}
  , idx
  , len = 2000000
  , tmp = 0
  , $results = $("#results")
  , $browser = $("#browser")
  ;

 $browser.html(navigator.userAgent);
 $results.html('');

 for (var i = 0; i < len; i++) {
  var number = Math.random(); //若希望加快運(yùn)算速度可使用取整:Math.random() * 10 | 0
  testArray.push(number);
  testObject[i] = number;
 }

 $results.append('<tr><th>測(cè)試代碼</th><th>計(jì)算結(jié)果</th><th>所需時(shí)間,毫秒</th></tr>');

 //測(cè)試函數(shù)
 var test = function(testFunc) {
  var startTime
   , endTime
   , result
   ;

  startTime = new Date();
  tmp = 0;
  testFunc();
  endTime  = new Date();

  //計(jì)算測(cè)試用例(Test Case)運(yùn)行所需要的時(shí)間
  result = endTime - startTime;
  $results.append('<tr><td><pre>{0}</pre></td><td>{1}</td><td>{2}</td></tr>'.format(testFunc.toString(), tmp | 0, result));
 };


 test(function() {
  //測(cè)試for in 的效率
  for (idx in testArray) {
   tmp += testArray[idx]; //經(jīng)測(cè)試,idx是string類(lèi)型,可能是慢的原因之一
  }
 });

 test(function() {
  //測(cè)試for loop循環(huán)的效率
  for (idx = 0, len = testArray.length; idx < len; idx++) {
   tmp += testArray[idx];
  }
 });

 test(function() {
  //測(cè)試forEach的效率
  testArray.forEach(function(data) {
   tmp += data;
  });
 });

 test(function() {
  //測(cè)試不緩存Array.length時(shí)效率
  for (idx = 0; idx < testArray.length; idx++) {
   tmp += testArray[idx];
  }
 });

 test(function() {
  //測(cè)試使用{} (Object) 存健值對(duì)時(shí),使用for in的效率如何
  for (idx in testObject) {
   tmp += testObject[idx];
  }
 });
 
 test(function() {
  //測(cè)試從{} Object查值時(shí)的效率如何(這里的健key值事先己知)
  for (idx = 0, len = testArray.length; idx < len; idx++) {
   tmp += testObject[idx];
  }
 });

}

運(yùn)行 [需稍等片刻]
測(cè)試結(jié)果
測(cè)試結(jié)果可能因計(jì)算而異,這是在我機(jī)器上運(yùn)行用,F(xiàn)irefox, Chrome, IE三者測(cè)試結(jié)果拼接的一張匯總。

2016313110044207.jpg (971×678)

以下是幾個(gè)觀察到的結(jié)論

  • for in比f(wàn)or loop慢非常多,在Chrome中至少慢20倍
  • FF對(duì)forEach(ES5)做了優(yōu)化,性能比f(wàn)or loop還要好一點(diǎn),但Chrome/IEn性能均較差
  • FF/Chrome緩存Array.length均比直接用時(shí)要慢一點(diǎn)。除IE最新版緩存后性能提升微乎其微(這一點(diǎn)非常意外)
  • 在某些情況下,F(xiàn)F的JS引擎性能似乎比V8要好些

相關(guān)文章

  • JS實(shí)現(xiàn)的合并多個(gè)數(shù)組去重算法示例

    JS實(shí)現(xiàn)的合并多個(gè)數(shù)組去重算法示例

    這篇文章主要介紹了JS實(shí)現(xiàn)的合并多個(gè)數(shù)組去重算法,涉及javascript數(shù)組遍歷、判斷、運(yùn)算、排序等相關(guān)操作技巧,需要的朋友可以參考下
    2018-04-04
  • 一些老手都不一定知道的JavaScript技巧

    一些老手都不一定知道的JavaScript技巧

    這篇文章主要介紹了一些老手都不一定知道的JavaScript技巧,需要的朋友可以參考下
    2014-05-05
  • 利用Javascript仿Excel的數(shù)據(jù)透視分析功能

    利用Javascript仿Excel的數(shù)據(jù)透視分析功能

    這篇文章給大家介紹了如何利用Javascript實(shí)現(xiàn)類(lèi)似Excel的數(shù)據(jù)透視分析功能,感興趣的朋友們可以參考借鑒,下面來(lái)一起看看吧。
    2016-09-09
  • 深入了解JavaScript中的垃圾回收機(jī)制

    深入了解JavaScript中的垃圾回收機(jī)制

    JavaScript中的垃圾回收機(jī)制負(fù)責(zé)自動(dòng)管理內(nèi)存,回收不再使用的對(duì)象所占用的內(nèi)存空間。本文主要介紹了JS中垃圾回收機(jī)制的相關(guān)知識(shí),需要的可以參考一下
    2023-04-04
  • JavaScript中的簡(jiǎn)寫(xiě)語(yǔ)法分享

    JavaScript中的簡(jiǎn)寫(xiě)語(yǔ)法分享

    這篇文章主要為大家整理了12個(gè)JavaScript中常用的簡(jiǎn)寫(xiě)語(yǔ)法技巧,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,需要的小伙伴可以收藏一下
    2023-04-04
  • js實(shí)現(xiàn)無(wú)縫輪播圖特效

    js實(shí)現(xiàn)無(wú)縫輪播圖特效

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)無(wú)縫輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • 微信小程序前后端數(shù)據(jù)交互的詳細(xì)圖文教程

    微信小程序前后端數(shù)據(jù)交互的詳細(xì)圖文教程

    這篇文章主要給大家介紹了關(guān)于微信小程序前后端數(shù)據(jù)交互的相關(guān)資料,通過(guò)小程序向后端發(fā)送請(qǐng)求,然后后端從數(shù)據(jù)庫(kù)獲取車(chē)源和求購(gòu)的數(shù)量反饋給小程序,最后將這兩個(gè)數(shù)據(jù)顯示出來(lái),需要的朋友可以參考下
    2022-10-10
  • JS中call和apply函數(shù)用法實(shí)例分析

    JS中call和apply函數(shù)用法實(shí)例分析

    這篇文章主要介紹了JS中call和apply函數(shù)用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了call和apply函數(shù)繼承功能的使用方法、區(qū)別及操作注意事項(xiàng),需要的朋友可以參考下
    2018-06-06
  • JavaScript圣杯布局與雙飛翼布局實(shí)現(xiàn)案例詳解

    JavaScript圣杯布局與雙飛翼布局實(shí)現(xiàn)案例詳解

    這篇文章主要介紹了JavaScript圣杯布局與雙飛翼布局實(shí)現(xiàn)案例,這是前端面試中需要掌握的知識(shí)點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 詳解js常用分割取字符串的方法

    詳解js常用分割取字符串的方法

    這篇文章主要介紹了js常用分割取字符串的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05

最新評(píng)論