簡體   English   中英

為什么LINQ不緩存枚舉?

[英]Why does LINQ not cache enumerations?

因此我理解LINQ不會立即執行所有操作,它只是存儲信息以獲取數據。 因此,如果您執行Where ,實際上沒有任何事情發生在列表中,您只需獲得一個IEnumerable ,它具有成為列表所需的信息。

通過調用ToList可以將此信息“折疊”到實際列表中。

現在我想知道,為什么LINQ團隊會像這樣實現它? 在每個步驟(或Dictionary )添加一個List來緩存已經計算過的結果非常容易,所以我想必須有一個很好的理由。

這可以通過以下代碼檢查:

var list = Enumerable.Range(1, 10).Where(i => {
    Console.WriteLine("Enumerating: " + i);
    return true;
});

var list2 = list.All(i => {
    return true;
});

var list3 = list.Any(i => {
    return false;
});

如果緩存在那里,它只會輸出Enumerating: i對於每個數字,它將第二次從緩存中獲取項目。

編輯:其他問題,為什么LINQ不包含緩存選項? .Cache()一樣緩存前一個可枚舉的結果?

在每一步添加List非常容易

是的,內存密集。 如果數據集總共包含2 GB數據,並且您必須立即將其存儲在內存中,該怎么辦? 如果你迭代它並分批獲取它,你就沒有很大的內存壓力。 當您將2 GB序列化為內存時,不要想象如果每個步驟都會這樣做會發生什么......

您知道您的代碼和您的特定用例,因此只有您作為開發人員才能確定何時將一些迭代拆分到內存是有用的。 框架無法知道。

因為它沒有意義,如果你想到所有沒有意義的情況,你就不會問它。 這不是一個“它有時是否有意義”的問題,因為“有副作用使它變壞”。 下次評估這樣的事情時,請考慮否定因素:

  • 即使不想要,也需要緩存結果,因此內存消耗會增加。
  • 然后在ext運行時,結果可能會有所不同,因為傳入的數據可能已更改。 您的簡單示例(Enumerable.Range)沒有問題 - 但過濾客戶列表可能會更新它們。

這樣的東西很難明智地從開發者那里拿走選擇。 想要一個緩沖區,做一個(輕松)。 但副作用會很糟糕。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM