Originally i wanted to know whether ToList
allocates more memory than using the constructor of List<T>
which takes an IEnumerable<T>
(no difference).
For test purposes i used Enumerable.Range
to create a source array that i could use to create an instance of List<int>
via 1.ToList
and 2.constructor. Both are creating copies.
This is how I came to notice a great difference in memory consumption between:
Enumerable.Range(1, 10000000)
orEnumerable.Range(1, 10000000).ToArray()
When i use the first and call ToList
the resulting object ineeds ~60% more memory than the Array(38,26MB/64MB).
Q: What is the reason for this or where is my error in reasoning?
var memoryBefore = GC.GetTotalMemory(true);
var range = Enumerable.Range(1, 10000000);
var rangeMem = GC.GetTotalMemory(true) - memoryBefore; // negligible
var list = range.ToList();
var memoryList = GC.GetTotalMemory(true) - memoryBefore - rangeMem;
String memInfoEnumerable = String.Format("Memory before: {0:N2} MB List: {1:N2} MB"
, (memoryBefore / 1024f) / 1024f
, (memoryList / 1024f) / 1024f);
// "Memory before: 0,11 MB List: 64,00 MB"
memoryBefore = GC.GetTotalMemory(true);
var array = Enumerable.Range(1, 10000000).ToArray();
var memoryArray = GC.GetTotalMemory(true) - memoryBefore;
list = array.ToList();
memoryList = GC.GetTotalMemory(true) - memoryArray;
String memInfoArray = String.Format("Memory before: {0:N2} MB Array: {1:N2} MB List: {2:N2} MB"
, (memoryBefore / 1024f) / 1024f
, (memoryArray / 1024f) / 1024f
, (memoryList / 1024f) / 1024f);
// "Memory before: 64,11 MB Array: 38,15 MB List: 38,26 MB"
list.TrimExcess();
on line 5 instead of initializing list to the exact size. – Dinkyrange.Count()
and useAddRange(range)
afterwards. – Burgin