js数组查找最接近_在JavaScript数组中找到最小元素的位置
在JavaScript數(shù)組中找到最小元素的位置
注* ?之前有篇文章介紹過數(shù)據(jù)遍歷的性能比較:?for in 比for loop慢至少20倍?,這是另外一篇比較數(shù)組查找性能的例子,通過對手工/indexOf/reduce三者的比較,再次映證,內(nèi)置函數(shù)不一下比手工寫的函數(shù)快。
今天的小程序甚至不是一個(gè)程序。這只是一個(gè)函數(shù)。
問題陳述如下:給定一個(gè)非空的JavaScript數(shù)字?jǐn)?shù)組,找到最小值的索引。(如果最小值出現(xiàn)不止一次,那么任何此類索引是可以接受的。)
一個(gè)解決方案是進(jìn)行簡單的手動(dòng)操作,模擬用紙筆如何執(zhí)行操作:首先,你假設(shè)第一個(gè)元素是贏家,然后你遍歷其他元素。如果你的下一個(gè)元素小于第一個(gè)元素,那么你聲明這個(gè)元素是新的臨時(shí)的贏家。function?indexOfSmallest(a)?{
var?lowest?=?0;
for?(var?i?=?1;?i?
if?(a[i]?
}
return?lowest;
}
另一種解決方案是使用reduce內(nèi)聯(lián)函數(shù)本質(zhì)來運(yùn)行循環(huán),所以你只需要提供初始猜測和if語句的業(yè)務(wù)邏輯。function?indexOfSmallest(a)?{
return?a.reduce(function(lowest,?next,?index)?{
return?next?
0);
}
第三個(gè)解決方案是使用JavaScript?內(nèi)聯(lián)函數(shù)找到最小的元素,然后將元素轉(zhuǎn)換為其索引。function?indexOfSmallest(a)?{
return?a.indexOf(Math.min.apply(Math,?a));
}
哪一個(gè)最快呢?
好吧,首先,你確定哪一個(gè)是最快之前,您需要確保他們都是正確的。你發(fā)現(xiàn)的一件事是,一旦數(shù)組變得很大最小/索引技術(shù)會(huì)失敗,至少它在IE瀏覽器和Firefox上是這樣的。(在我的例子中,Internet?Explorer和Firefox分別放棄了元素?cái)?shù)量約為250000和500000的數(shù)組)。那是因?yàn)槟汩_始觸及引擎的數(shù)量限制參數(shù),這個(gè)參數(shù)你可以傳遞給一個(gè)函數(shù)。調(diào)用250000個(gè)元素的數(shù)組相當(dāng)于最少調(diào)用250000個(gè)函數(shù)參數(shù)。所以我們會(huì)限制自己的數(shù)組長度最多為250000。分享結(jié)果之前,我想讓你猜猜哪個(gè)算法你認(rèn)為將是最快和哪個(gè)是最慢的。
仍然在等。
我預(yù)計(jì)手工版本是最后一名,因?yàn)?畢竟,這是手工做的一切。我預(yù)計(jì)使用減少函數(shù)的版本稍快,因?yàn)樗岩恍┕ぷ鹘唤o了內(nèi)聯(lián)函數(shù)(盡管上面的函數(shù)調(diào)用可能否定了它的改進(jìn))。我預(yù)計(jì)min/?indexOf版本是最快的,因?yàn)閹缀跛械墓ぷ髟趦?nèi)聯(lián)函數(shù)中完成,并且兩次數(shù)據(jù)遍歷的開銷將會(huì)由內(nèi)聯(lián)函數(shù)的一些改進(jìn)性能構(gòu)成。
這里有三個(gè)版本在不同大小的數(shù)組上的計(jì)時(shí),它是運(yùn)行在隨機(jī)數(shù)據(jù)上。我正常運(yùn)行了好幾次,所以這個(gè)結(jié)果與CPU速度是獨(dú)立的。
每個(gè)數(shù)組元素相對運(yùn)行時(shí)間元素手工reducemin/indexOf
Internet?Explorer?9
100,0001.0002.1552.739
200,0001.0142.3243.099
250,0001.0232.2002.330
Internet?Explorer?10
100,0001.0004.0574.302
200,0001.0284.0574.642
250,0001.0194.0914.068
你感到驚訝嗎?我肯定我很驚訝!
我不僅完全向后又運(yùn)算了一遍,但手工版本勝利的界限的是超出了我的想象的。
(這表明要知道程序的性能,唯一途徑肯定是坐下來測量它。)
我認(rèn)為正在發(fā)生的是,JavaScript優(yōu)化器可以很好地優(yōu)化手工代碼,因?yàn)樗浅:唵巍?循環(huán)體沒有函數(shù)調(diào)用,只是一行,在外面沒關(guān)系的。使用內(nèi)聯(lián)函數(shù)的版本以從優(yōu)化器隱藏一些信息結(jié)束。(畢竟,優(yōu)化器不能提前預(yù)測是否有人覆蓋Array.prototype.reduce或者M(jìn)ath.prototype.min的默認(rèn)實(shí)現(xiàn),所以不能盲目的內(nèi)聯(lián)調(diào)用。)結(jié)果是,在IE9瀏覽器上運(yùn)行手動(dòng)版本可以快兩倍,在IE10上運(yùn)行速度超過四倍。
我弄錯(cuò)了,因?yàn)槲蚁肫鹆薐avaScript太像一種解釋型語言。在一個(gè)純粹的解釋型語言,翻譯的開銷大約與你讓它做的事情的數(shù)量成正比,而不是與做這些事情是多么難成正比。就像一個(gè)對每一筆交易固定的服務(wù)費(fèi),不管交易是100美元50美分。你因此試圖做一筆大的買賣(調(diào)用復(fù)雜的內(nèi)聯(lián)函數(shù))而不是大量的小買賣(讀一個(gè)數(shù)組元素,比較兩個(gè)值,增加一個(gè)變量,一個(gè)變量復(fù)制到另一個(gè))。
福利:我在Firefox上做了這個(gè)測試,因?yàn)槲遗銮杀容^方便。
每個(gè)數(shù)組元素相對運(yùn)行時(shí)間元素手工reducemin/indexOf
Firefox?16
100,0001.00021.5983.958
200,0000.84821.7012.515
250,0000.83921.7882.090
相同的數(shù)據(jù)收集在Firefox?16(這聽起來是可笑的老舊版本,因?yàn)榈竭@篇文章到達(dá)隊(duì)列頭部的時(shí)候,Firefox將發(fā)行523版本)展示了一個(gè)不同的形象,盡管勝利者是相同的。數(shù)組大小增加的時(shí)候手動(dòng)循環(huán)和min/?indexOf變得更高效。這表明,當(dāng)你增加數(shù)據(jù)集的大小,固定的開銷逐漸變得不那么重要。
一件比較突出的事是,reduce()方法表現(xiàn)地比其他方法差。我的猜測是,設(shè)置函數(shù)調(diào)用(為了內(nèi)聯(lián)函數(shù)和腳本之間的轉(zhuǎn)換)開銷是很大的,并且JavaScript引擎實(shí)現(xiàn)器沒有花任何時(shí)間優(yōu)化這種案例,因?yàn)閞educe在實(shí)際代碼中不常使用。
更新:我夸大了我構(gòu)造一個(gè)好的故事敘述的天真。就像我書的序言中指出的那樣,我的故事也許并不完全正確,但他們已經(jīng)足夠真實(shí)。我當(dāng)然知道JavaScript?如今是JITTED(即時(shí)解釋執(zhí)行),它改變了計(jì)算方式。(同時(shí),是隱藏的數(shù)組副本。)
總結(jié)
以上是生活随笔為你收集整理的js数组查找最接近_在JavaScript数组中找到最小元素的位置的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 五省竞赛计算机作品,关于征集2017年华
- 下一篇: SpringBoot xml层SQL u