短路邏輯(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
static
void
main(
string
args)
system.console.writeline(
"short-circuit logic test end"
);
system.console.read();
}
static
bool
conditiona()
static
bool
conditionb()
輸出: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
class
userinfo
}
class
program
,
new
userinfo,
new
userinfo
};
var
query = 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
class
userinfo
}
class
program
);
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框架,它使得運算元據庫就像操作記憶體中的資料一樣,但是這種抽象是有效能代價的,故...