C 延遲執行

2022-02-21 13:08:26 字數 2406 閱讀 2168

借鑑於該篇部落格:

先看兩個方法

public class yieldclasses

return list;

}public static ienumerablewithyied()}}

分別用執行他們接過是怎樣

yieldclasses.withnoyied();

yieldclasses.withyied();??????

令人驚訝的是:第乙個函式跟預期的一樣,從1輸到99。而第二個函式卻什麼 也沒有輸出!這是神馬回事???

我們再foreach中迭代兩個函式

foreach (var item in

yieldclasses.withnoyied())

結果:withyied的結果

withnoyied的結果:

1233456789101112.。。。。。。。0-1-2-3-4-5-6-7-8-9-10.。。。(突然截圖不行了)

這是神馬回事呢?

從顯示的結果可以看出,在withnoyied中,是先迴圈

執行完函式中的console.write,再執行main中的write

而在withyied中,是迴圈一次,先執行函式中的wirte,再執行main中的write,再迴圈下一次。。。。

這就是癥結所在!明之:yield的延遲執行!

2/ 這裡有用il的方法分析。我就簡單的總結以下吧:

延遲計算(lazy evaluation或delayed evaluation)在wiki上可以找到它的解釋:將計算延遲,直到需要這個計算的結果的時候才計算,這樣就可以因為避免一些不必要的計算而改進效能,在合成一些表示式時候還可以避免一些不必要的條件,因為這個時候其他計算都已經完成了,所有的條件都已經明確了,有的根本不可達的條件可以不用管了。反正就是好處很多了。

延遲計算**自函式式程式設計,在函式式程式設計裡,將函式作為引數來傳遞,你想呀,如果這個函式一傳遞就被計算了,那還搞什麼搞,如果你使用了延遲計算,表示式在沒有使用的時候是不會被計算的,比如有這樣乙個應用:x=expression,將這個表示式賦給x變數,但是如果x沒有在別的地方使用的話這個表示式是不會被計算的,在這之前x裡裝的是這個表示式。

延遲計算在linq中的應用:

看看下面的方法:

public

static

void  linqtest()

;int a=0;

var result = from item in intarray

select item;

if(a==0)}}

這樣的方法,如果a==0,那會輸出結果(先執行linq操作),但如果a!=0,那麼linq操作就不執行!

result是乙個實現了ienumerable介面的類(在linq裡,所有實現了ienumerable介面的類都被稱作sequence),對它的foreach或者while的訪問必須通過它對應的ienumerator的movenext()方法,如果我們把一些耗時的或者需要延遲的操作放在movenext()裡面,那麼只有等到movenext()被訪問,也就是result被使用的時候那些操作才會執行,而給result賦值啊,傳遞啊,什麼的,那些耗時的操作都沒有被執行。

如果上面這段**,最後由於state小於0,而對result沒有任何需求了,在linq裡返回的結果都是ienumerable的,如果這裡沒有使用延遲計算,那那個linq表示式不就白運算了麼?如果是linq to objects還稍微好點,如果是linq to sql,而且那個資料庫表又很大,真是得不償失啊,所以微軟想到了這點,這裡使用了延遲計算,只有等到程式別的地方使用了result才會計算這裡的linq表示式的值的,這樣linq的效能也比以前提高了不少,而且linq to sql最後還是要生成sql語句的,對於sql語句的生成來說,如果將生成延遲,那麼一些條件就先確定好了,生成sql語句的時候就可以更精練了。還有,由於movenext()是一步步執行的,迴圈一次執行一次,所以如果有這種情況:我們遍歷一次判斷一下,不滿足我們的條件了我們就退出,如果有一萬個元素需要遍歷,當遍歷到第二個的時候就不滿足條件了,這個時候我們就可就此退出,後面那麼多元素實際上都沒處理呢,那些元素也沒有被載入到記憶體中來。

延遲計算還有很多惟妙惟肖的特質,也許以後你也可以按照這種方式來程式設計了呢。寫到這裡我突然想到了command模式,command模式將方法封裝成類,command物件在傳遞等時候是不會執行任何東西的,只有呼叫它內部那個方法他才會執行,這樣我們就可以把命令到處發,還可以壓棧啊等等而不擔心在傳遞過程中command被處理了,也許這也算是一種延遲計算吧。

C 延遲執行 Lazy

在.net4.0中,可以使用lazy來實現物件的延遲初始化,提供了執行緒安全的延遲呼叫,從而優化系統的效能。延遲初始化就是將物件的初始化延遲到第一次使用該物件時。延遲初始化是我們在寫程式時經常會遇到的情形,例如建立某一物件時需要花費很大的開銷,而這一物件在系統的執行過程中不一定會用到,這時就可以使用...

Linq to sql 延遲執行

iqueryable query from c in ctx.customers selectc 這樣的查詢句法不會導致語句立即執行,它僅僅是乙個描述,對應乙個 sql。僅僅在 需要使用的時候才會執行語句,比如 iqueryable query from c in ctx.customers sel...

Linq 延遲執行

使用linq時,其中乙個重要概念就是延遲執行,所有的謂詞求值需要等到觸發時才會被呼叫。在宣告時,它們是不執行的,除非呼叫lambda表示式,造成其中的 開始執行,否則不會被執行。如果lambda表示式執行的代價比較高 如呼叫資料庫,密集計算等 那麼為了優化 通過使用 to 方法來轉換為集合方式,減少...