もともと私はToList
、コンストラクターを使用するよりも多くのメモリーを割り当てるかどうかを知りたいと思っていましList<T>
たIEnumerable<T>
(違いはありません)。
テストの目的で、1。および2.コンストラクターを介しEnumerable.Range
てインスタンスを作成するために使用できるソース配列を作成するために使用しました。どちらもコピーを作成しています。List<int>
ToList
このようにして、次のメモリ消費量に大きな違いがあることに気づきました。
Enumerable.Range(1, 10000000)
またEnumerable.Range(1, 10000000).ToArray()
最初のオブジェクトを使用しToList
て結果のオブジェクトを呼び出すと、配列(38,26MB / 64MB)よりも最大60%多くのメモリが必要になります。
Q:これの理由は何ですか、または推論の誤りはどこにありますか?
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"