亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Lodash chain功能(Lazy Evaluation)介紹

SegmentFault / 1534人閱讀

摘要:幾乎完美結(jié)合了各種各樣的技術(shù)來(lái)榨干了的性能。它使用了最快的語(yǔ)句,自適應(yīng)的算法,它甚至進(jìn)行性能測(cè)試以避免在后續(xù)發(fā)布的版本中意外的降低了性能。這就是中背后的基本思想減少循環(huán)的次數(shù)而不是減少每次循環(huán)的時(shí)間。

原文:http://filimanjaro.com/blog/2...

我曾經(jīng)一直認(rèn)為像Lodash這樣的庫(kù)是不可能正的比它們已有的速度更快的。Lodash幾乎完美結(jié)合了各種各樣的技術(shù)來(lái)榨干了JavaScript的性能。它使用了JavaScript最快的語(yǔ)句,自適應(yīng)的算法,它甚至進(jìn)行性能測(cè)試以避免在后續(xù)發(fā)布的版本中意外的降低了性能。

惰性計(jì)算Lazy Evaluation

但是貌似我錯(cuò)了——實(shí)際上我們能讓Lodas運(yùn)行速度得到明顯提升。而你所需要做的僅僅只是停止考慮一些微觀的優(yōu)化,然后找到并使用更好的算法。例如,在一個(gè)典型的循環(huán)中,我們通常傾向于優(yōu)化每次迭代的時(shí)間:

var len = getLength();
for(var i = 0; i < len; i++) {
    operation(); // <- 10ms - how to make it 9ms?!
}

但是這樣的優(yōu)化很有限而且很難做到優(yōu)化。相反的,在某些情況下優(yōu)化getLength()函數(shù)卻有意義的多。getLength()函數(shù)返回的數(shù)字越小,我們要執(zhí)行的10ms的循環(huán)次數(shù)就越少。
這就是Lodash中l(wèi)azy evaluation背后的基本思想:減少循環(huán)的次數(shù)而不是減少每次循環(huán)的時(shí)間。讓我們看一看下面的例子:

function priceLt(x) {
   return function(item) { return item.price < x; };
}
var gems = [
   { name: "Sunstone", price: 4 }, { name: "Amethyst", price: 15 },
   { name: "Prehnite", price: 20}, { name: "Sugilite", price: 7  },
   { name: "Diopside", price: 3 }, { name: "Feldspar", price: 13 },
   { name: "Dioptase", price: 2 }, { name: "Sapphire", price: 20 }
];

var chosen = _(gems).filter(priceLt(10)).take(3).value();

我們只想提取3個(gè)價(jià)格低于$10的寶石(gem)。常規(guī)Lodash方法(Strict evaluation)先篩選所有的8個(gè)寶石,然后返回前三個(gè)通過(guò)篩選的寶石。如下圖:

然而,這還不夠酷。它處理了所有的8個(gè)元素,然而實(shí)際上我們只需要讀取其中的5個(gè)元素。相反的,Lazy evaluation算法只處理數(shù)組中最少的元素?cái)?shù)量即可獲得正確的結(jié)果,看如下實(shí)例:

這樣我們就輕松的獲取了37.5%的性能提升,但37.5%不是我們所能達(dá)到的極限,實(shí)際上很容易就能找到一個(gè)帶來(lái)100倍性能提升的例子。讓我們看下面的例子:

var phoneNumbers = [5554445555, 1424445656, 5554443333, … ×99,999];

// get 100 phone numbers containing ?55”
function contains55(str) {
    return str.contains("55"); 
};

var r = _(phoneNumbers).map(String).filter(contains55).take(100);

在這個(gè)例子中,map和filter要在99999個(gè)元素上執(zhí)行,而實(shí)際上,它有可能只需要在少數(shù)元素,例如1000個(gè)元素上運(yùn)行就足夠了,在這個(gè)例子中,Lazy evaluation帶來(lái)的性能提升非常巨大(benchmark)

Pipelining

Lazy evaluation帶來(lái)的另外一個(gè)好處被稱為"pipelineing",這個(gè)概念背后的思想是避免在鏈?zhǔn)綀?zhí)行(chain execution)中創(chuàng)建中間數(shù)組。我們應(yīng)該在一個(gè)元素上原地執(zhí)行所有的操作。所以下面的代碼

var result = _(source).map(func1).map(func2).map(func3).value();

在regulaer Lodash常規(guī)計(jì)算中(strict evaluation)將大致的轉(zhuǎn)換為這樣:

var result = [], temp1 = [], temp2 = [], temp3 = [];

for(var i = 0; i < source.length; i++) {
   temp1[i] = func1(source[i]);
}

for(i = 0; i < source.length; i++) {
   temp2[i] = func2(temp1[i]);
}

for(i = 0; i < source.length; i++) {
   temp3[i] = func3(temp2[i]);
}
result = temp3;

而如果在惰性計(jì)算(lazy evaluation)打開(kāi)以后,它將像這樣執(zhí)行:

var result = [];
for(var i = 0; i < source.length; i++) {
   result[i] = func3(func2(func1(source[i])));
}

沒(méi)有臨時(shí)數(shù)組將給我們帶來(lái)顯著的性能提升,當(dāng)源數(shù)組巨大并且內(nèi)存訪問(wèn)開(kāi)銷很大時(shí)提升更加明顯。

延遲執(zhí)行(Deferred execution)

和lazy evaluation一起帶來(lái)的另外一個(gè)好處就是延遲執(zhí)行(deferred execution),不管什么時(shí)候你創(chuàng)建了一個(gè)chain,在顯式或者隱式調(diào)用.value()方法前它都不會(huì)計(jì)算。這個(gè)特性使我們能先準(zhǔn)備一個(gè)查詢,然后再在在最新的數(shù)據(jù)上執(zhí)行這個(gè)查詢。

var wallet = _(assets).filter(ownedBy("me"))
                      .pluck("value")
                      .reduce(sum);

$json.get("/new/assets").success(function(data) {
    assets.push.apply(assets, data); // update assets
    wallet.value(); // returns most up-to-date value
});

同時(shí)因?yàn)長(zhǎng)azy evaluation可也以加速執(zhí)行時(shí)間,所以在運(yùn)行時(shí)間很重要的時(shí)候,我們可以提前創(chuàng)建一個(gè)復(fù)雜的查詢,然后再執(zhí)行它。

Wrap up

Lazy evaluation在行業(yè)中并不是一個(gè)新想法,它已經(jīng)在例如LINQ,Lazy.js和很多其它的優(yōu)秀的庫(kù)中存在了。我認(rèn)為L(zhǎng)odash不同于他們的地方主要在于你仍然擁有一個(gè)外表和Underscore一樣的API,但內(nèi)部卻是一個(gè)新的強(qiáng)大的引擎。不需要學(xué)習(xí)新的庫(kù),不需要更改大量的代碼,就像只是一個(gè)附加的更新一樣。
但是,即使你沒(méi)有打算使用Lodash,我也希望這篇文章能給你帶來(lái)一點(diǎn)啟發(fā):當(dāng)你發(fā)現(xiàn)你的應(yīng)用中的瓶頸時(shí),不要在jsperf.com中try/fail的來(lái)優(yōu)化它,而是起身,沖一杯咖啡,然后開(kāi)始考慮一下算法。在這里創(chuàng)新的確很重要,但是良好的數(shù)學(xué)背景不會(huì)有害(推薦書目),祝你好運(yùn)!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/87940.html

相關(guān)文章

  • 惰性求值——lodash源碼解讀

    摘要:本文將講述源碼中,惰性求值的原理和實(shí)現(xiàn)。惰性求值中的參數(shù)直到需要時(shí)才會(huì)進(jìn)行計(jì)算。執(zhí)行的示例圖如下惰性求值做法普通的做法存在一個(gè)問(wèn)題每個(gè)方法各做各的事,沒(méi)有協(xié)調(diào)起來(lái)浪費(fèi)了很多資源。 前言 lodash受歡迎的一個(gè)原因,是其優(yōu)異的計(jì)算性能。而其性能能有這么突出的表現(xiàn),很大部分就來(lái)源于其使用的算法——惰性求值。本文將講述lodash源碼中,惰性求值的原理和實(shí)現(xiàn)。 一、惰性求值的原理分析 惰性...

    tianren124 評(píng)論0 收藏0
  • lazy.js 惰性求值實(shí)現(xiàn)分析

    摘要:同時(shí)還定義了接口,使得其下級(jí)可以從這里得到一個(gè)迭代器,對(duì)于該進(jìn)行遍歷。迭代器在中也是一個(gè)約定的協(xié)議,實(shí)現(xiàn)該協(xié)議的對(duì)象要支持和兩個(gè)接口方法。從迭代器的邏輯中,可以看到,當(dāng)對(duì)象作為其他的上級(jí)時(shí),如果實(shí)現(xiàn)上傳下達(dá)。 背景:惰性求值? 來(lái)看一個(gè) lazy.js 主頁(yè)提供的示例: var people = getBigArrayOfPeople(); var results = _.chain(...

    Forelax 評(píng)論0 收藏0
  • 2018年你應(yīng)該知道的11個(gè)Javascript實(shí)用程序庫(kù)

    摘要:構(gòu)建是為了在中為常見(jiàn)任務(wù)提供實(shí)用程序功能。所有功能都自動(dòng)進(jìn)行,并且相應(yīng)地安排傳遞的參數(shù)以便于使用。在星級(jí),是一個(gè)用于處理本機(jī)對(duì)象的實(shí)用程序庫(kù)。該庫(kù)沒(méi)有外部依賴關(guān)系,這是一個(gè)將事件作為序列進(jìn)行測(cè)試的現(xiàn)場(chǎng)演示。 由于Javascript在2018年仍然是最受歡迎和最廣泛使用的編程語(yǔ)言,因此圍繞它擴(kuò)展了生態(tài)系統(tǒng)。 showImg(https://segmentfault.com/img/re...

    Ali_ 評(píng)論0 收藏0
  • 2018年你應(yīng)該知道的11個(gè)Javascript實(shí)用程序庫(kù)

    摘要:構(gòu)建是為了在中為常見(jiàn)任務(wù)提供實(shí)用程序功能。所有功能都自動(dòng)進(jìn)行,并且相應(yīng)地安排傳遞的參數(shù)以便于使用。在星級(jí),是一個(gè)用于處理本機(jī)對(duì)象的實(shí)用程序庫(kù)。該庫(kù)沒(méi)有外部依賴關(guān)系,這是一個(gè)將事件作為序列進(jìn)行測(cè)試的現(xiàn)場(chǎng)演示。 由于Javascript在2018年仍然是最受歡迎和最廣泛使用的編程語(yǔ)言,因此圍繞它擴(kuò)展了生態(tài)系統(tǒng)。 showImg(https://segmentfault.com/img/re...

    Yumenokanata 評(píng)論0 收藏0
  • js函數(shù)式編程術(shù)語(yǔ)總結(jié)

    摘要:而純函數(shù),主要強(qiáng)調(diào)相同的輸入,多次調(diào)用,輸出也相同且無(wú)副作用。對(duì)于組合可能不返回值的函數(shù)很有用在其它的一些地方,也稱為,也稱為,也稱為 參考文檔1 參考文檔2 函數(shù)式編程術(shù)語(yǔ) 高階函數(shù) Higher-Order Functions 以函數(shù)為參數(shù)的函數(shù) 返回一個(gè)函數(shù)的函數(shù) 函數(shù)的元 Arity 比如,一個(gè)帶有兩個(gè)參數(shù)的函數(shù)被稱為二元函數(shù) 惰性求值 Lazy evaluation 是...

    番茄西紅柿 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<