短路邏輯和延遲載入

2021-06-22 16:47:15 字數 4061 閱讀 9438

短路邏輯(short-circuit logic)也叫懶惰求值(lazy evaluation),在我們熟知的布林運算中有乙個非常有趣的特性:只有在需要求值時才進行求值。舉例來說,conditiona() and conditionb()需要兩個條件都為真時才是真,所以如果conditiona() 為假,表示式立刻返回false,而不會去計算conditionb()造成不必要的運算浪費。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

staticvoidmain(stringargs)

system.console.writeline("short-circuit logic test end");

system.console.read();

}

staticboolconditiona()

staticboolconditionb()

輸出:conditiona:false

short-circuit logic test end

如你看到的那樣,conditiona()為假,那麼conditionb()就被「短路」了,根本不需要去執行。這種「只有在需要求值時才進行求值」的特點體現了「按需」的思想,可以看做是一種樸素的延遲載入。

在實際開發中延遲載入的思想應用非常普遍,比如的按需載入、某些orm實現的查詢對關聯資料的載入等等。那麼什麼是延遲載入呢?

yield關鍵字的使用記得以前總結過,可參考這一篇。

yield語句只能出現在iterator(迭代器)塊中,我們可以把一些耗時的或者需要延遲的操作放在movenext()裡面。正是yield才使linq的延遲執行成為可能。

在linq中,所有實現了ienumerable介面的類都被稱作sequence(序列),linq最基本的資料單元是sequences和elements。乙個sequence是實現了ienumerable的物件,而乙個element是sequence中的每乙個元素。如下就是乙個簡單的linq查詢:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

classuserinfo

}

classprogram

,

newuserinfo,

newuserinfo

};

varquery = list.where(m => m.name.startswith("j"));//linq查詢

if(lang =="c#")

}

system.console.read();

}

}

上面示例**中有個if條件,就是當語言(lang)等於c#的時候輸出序列中的使用者(元素)的名稱。但是其實這個條件為假,所以對於linq查詢結果query根本沒有什麼作用,如果這是乙個耗時的查詢操作,偏偏查詢結果又用不到,那不是白做了嗎?好在在linq查詢實現中,query變數只是乙個可迭代列表(ienumerable)物件佔位符,它根本沒有進行計算,也沒有載入資料(這裡是使用者資訊)進入記憶體,只有在foreach遍歷取值的時候才會進行運算取值,顯然可以節省開銷。

當然,上例中我們構造的列表資料量很小,而且本身就在記憶體中,就算執行了查詢,好像也看不出效能上有多少提公升。但是實際上在我們熟知的linq to sql中,iqueryable就是繼承實現了ienumerable介面,使用linq to sql訪問資料庫,對於網路傳輸和io的影響就不得不考慮,否則很容易造成查詢緩慢使用者體驗惡劣。好在我們可以利用linq的延遲執行機制寫出良好的查詢,而且微軟的linq to sql和ado.net entity framework框架都支援對關聯資料的延遲載入機制。

.net中典型的延遲載入按需建立物件的類就是lazy,對於那種「懶物件」的建立非常簡單:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

classuserinfo

}

classprogram

);

if(!lazyuser.isvaluecreated)//使用者還沒有建立

console.writeline(lazyuser.value.name);//此時真正建立使用者

system.console.read();

}

}

實際上lazy可以給開發者提供更多的控制選項(比如支援委託)和執行緒安全。

參考:

短路邏輯和延遲載入

短路邏輯 short circuit logic 也叫懶惰求值 lazy evaluation 在我們熟知的布林運算中有乙個非常有趣的特性 只有在需要求值時才進行求值。舉例來說,conditiona and conditionb 需要兩個條件都為真時才是真,所以如果conditiona 為假,表示式...

延遲載入和預載入

在網頁剛開始開啟的時候,並沒有載入這些,滾動條移動到一定的位置才載入這些,這就是延遲載入的乙個例子。延遲載入的好處 使用延遲載入節約大量的流量資源。實現預載入的方法 1 將的實際的路徑位置放在xsrc中 2 得到距離視窗頂端的距離 3 獲取螢幕可視區域的最低點的位置 達到的時候實現1 在網頁開啟某一...

EF 延遲載入和預先載入

最近悟出來乙個道理,在這兒分享給大家 學歷代表你的過去,能力代表你的現在,學習代表你的將來。十年河東十年河西,莫欺少年窮 學無止境,精益求精 本節 延遲載入和預先載入 entity framework作為乙個優秀的orm框架,它使得運算元據庫就像操作記憶體中的資料一樣,但是這種抽象是有效能代價的,故...