I have the following code:
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.");
This prints out:
> Size of System.Int32: 4
> Iterating over 2147483647 elements... Done.
However, I don't understand why is this not throwing an OutOfMemoryException
.
Knowing that each int
value takes up 4
bytes of space, allocating Int32.MaxValue
amount of int
should take up ~ 8GB
Inspecting my application, the process is taking up aprox. ~ 5.200KB.
The elements are being iterated successfully so they must be allocated somewhere, right?
How does LINQ achieve this?
IEnumerable<int>
is not an array. It doesn't store any information itself. The class implementing it is capable of looping over a set of values.
The values here are not stored in an array, instead of that is just iterates and yields the result of every iteration.
Something like this:
public IEnumerable<int> GetRange(int start, int number)
{
for (int i = start; i < start + number; i++)
{
yield return i;
}
}
See, no arrays, no storage. It just remembers the current position in the iterator and can execute the appropriate steps to get the next one. This code is generated by the C# compiler on the fly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With