2015-10-19 48 views
4

我有以下代碼:Enumerable.Range和內存分配

IEnumerable<int> elements = Enumerable.Range(1, Int32.MaxValue); 
Console.WriteLine("Size of System.Int32: {0}", sizeof(int)); 
Console.Write("Iterating over {0} elements... ", elements.Count()); 
Parallel.ForEach(elements, _ => { }); 
Console.WriteLine("Done."); 

此打印出:

> Size of System.Int32: 4 
> Iterating over 2147483647 elements... Done. 

不過,我不明白這是爲什麼不引發OutOfMemoryException

他們知道每int值佔4字節的空間,分配的intInt32.MaxValue量應占〜8GB

檢查我的應用程序,這個過程aprox的佔用。 〜5.200KB。

元素正在迭代成功,所以他們必須分配到某個地方,對吧?

LINQ如何實現這一目標?

+0

我建議你看看https://en.wikipedia.org/wiki/Lazy_evaluation#Implementation,因爲懶惰評估是LINQ的全部內容! (和monads ofc!) – flindeberg

+0

不錯的嘗試,但c#設計師更聰明:P如果它是關於懶加載然後通過元素foreach會導致內存增加,我懷疑它,你 – mikus

+0

@mikus誰是一個評論?你知道懶惰加載和懶惰評估有區別嗎? (實際上是50%這個詞) – flindeberg

回答

12

IEnumerable<int>不是數組。它本身不存儲任何信息。實現它的類能夠循環使用一組值。

這裏的值不存儲在一個數組中,而不是隻是迭代併產生每次迭代的結果。

事情是這樣的:

public IEnumerable<int> GetRange(int start, int number) 
{ 
    for (int i = start; i < start + number; i++) 
    { 
     yield return i; 
    } 
} 

見,無陣列,無存儲。它只是記住迭代器中的當前位置,並且可以執行適當的步驟來獲取下一個。該代碼由C#編譯器實時生成。