Enumerable.Range 和内存分配
Enumerable.Range and Memory allocation
我有以下代码:
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
值占用 space 的 4
字节,分配 Int32.MaxValue
数量的 int
应该占用 ~ 8GB
检查我的应用程序,进程占用了大约。 ~ 5.200KB.
元素迭代成功,所以它们必须分配到某个地方,对吧?
LINQ 是如何做到这一点的?
IEnumerable<int>
不是数组。它本身不存储任何信息。 class 实现它能够循环一组值。
这里的值没有存储在数组中,而是只是迭代并产生每次迭代的结果。
像这样:
public IEnumerable<int> GetRange(int start, int number)
{
for (int i = start; i < start + number; i++)
{
yield return i;
}
}
看,没有数组,就没有存储。它只是记住迭代器中的当前位置,并可以执行适当的步骤以获得下一个。此代码由 C# 编译器即时生成。
我有以下代码:
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
值占用 space 的 4
字节,分配 Int32.MaxValue
数量的 int
应该占用 ~ 8GB
检查我的应用程序,进程占用了大约。 ~ 5.200KB.
元素迭代成功,所以它们必须分配到某个地方,对吧?
LINQ 是如何做到这一点的?
IEnumerable<int>
不是数组。它本身不存储任何信息。 class 实现它能够循环一组值。
这里的值没有存储在数组中,而是只是迭代并产生每次迭代的结果。
像这样:
public IEnumerable<int> GetRange(int start, int number)
{
for (int i = start; i < start + number; i++)
{
yield return i;
}
}
看,没有数组,就没有存储。它只是记住迭代器中的当前位置,并可以执行适当的步骤以获得下一个。此代码由 C# 编译器即时生成。