using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Collections; namespace ConsoleApplication2 { public class MemoryConsumptionTest { public readonly int LIST_SIZE = 1000000; private Random m_random = new Random(); private long m_memoryStart = 0; private long m_memoryMakeList = 0; private long m_memoryMakePresizedList = 0; private long m_memoryFilledList = 0; private long m_memoryFillPresizedList = 0; private long m_memorySecondList = 0; private long m_memoryListSortedPlusStatic = 0; private long m_memoryListSorted = 0; private long m_memoryCreatingArray = 0; private long m_memoryUsingArraySort = 0; private long m_memoryUsingArraySortSecond = 0; private int m_capacityListFilled = 0; public int CapacityListFilled { get { return m_capacityListFilled; } } private int m_capacityListCopiedIn = 0; public int CapacityListCopiedIn { get { return m_capacityListCopiedIn; } } public void TestListSort() { // Make sure that random is fully JITed int i = GetNextInt(); // make sure that the compiler can't reorder lines here Thread.MemoryBarrier(); m_memoryStart = System.GC.GetTotalMemory(true); List testList1 = new List(); Thread.MemoryBarrier(); m_memoryMakeList = System.GC.GetTotalMemory(true); List testListPresize = new List(LIST_SIZE); Thread.MemoryBarrier(); m_memoryMakePresizedList = System.GC.GetTotalMemory(true); for (i = 0; i < LIST_SIZE; i++) { testList1.Add(GetNextInt()); } Thread.MemoryBarrier(); m_memoryFilledList = System.GC.GetTotalMemory(true); testListPresize.AddRange(testList1); Thread.MemoryBarrier(); m_memoryFillPresizedList = System.GC.GetTotalMemory(true); List testList2 = new List(testList1); Thread.MemoryBarrier(); m_memorySecondList = System.GC.GetTotalMemory(true); testList1.Sort(); Thread.MemoryBarrier(); m_memoryListSortedPlusStatic = System.GC.GetTotalMemory(true); testList2.Sort(); Thread.MemoryBarrier(); m_memoryListSorted = System.GC.GetTotalMemory(true); Array array = testListPresize.ToArray(); Array array2 = testListPresize.ToArray(); Thread.MemoryBarrier(); m_memoryCreatingArray = System.GC.GetTotalMemory(true); Array.Sort(array); Thread.MemoryBarrier(); m_memoryUsingArraySort = System.GC.GetTotalMemory(true); Array.Sort(array2); Thread.MemoryBarrier(); m_memoryUsingArraySortSecond = System.GC.GetTotalMemory(true); // we need these references at the very end, so that testListPresize, // testList1 and testList2 are not GCed before. Because that // would of course falsify the memoryusage. i = testListPresize.Capacity; // make sure these i = ... can't be optimized out and therefore releasing // the references too early (see comment above). Thread.MemoryBarrier(); i = array.Length; Thread.MemoryBarrier(); i = array2.Length; Thread.MemoryBarrier(); m_capacityListFilled = testList1.Capacity; m_capacityListCopiedIn = testList2.Capacity; } public long GetImpactEmptyList() { return m_memoryMakeList - m_memoryStart; } public long GetImpactPresizedList() { return m_memoryMakePresizedList - m_memoryMakeList; } public long GetImpactFilledArray() { return m_memoryFilledList - m_memoryMakePresizedList; } public long GetImpactFillPresizedArray() { return m_memoryFillPresizedList - m_memoryFilledList; } public long GetImpactCreateAndFillSecondArray() { return m_memorySecondList - m_memoryFillPresizedList; } public long GetImpactStaticAndSort() { return m_memoryListSortedPlusStatic - m_memorySecondList; } public long GetImpactSort() { return m_memoryListSorted - m_memoryListSortedPlusStatic; } public long GetImpactStaticAndArraySort() { return m_memoryUsingArraySort - m_memoryCreatingArray; } public long GetImpactArraySortSecond() { return m_memoryUsingArraySortSecond - m_memoryUsingArraySort; } private int GetNextInt() { return m_random.Next(int.MinValue, int.MaxValue); } } }