List <t> </t>的意外内存使用情况

时间:2012-04-22 08:20:34

标签: c#-4.0

我一直认为List的默认构造函数会初始化容量为4的列表,并且在添加第5个元素时容量会加倍...

在我的应用程序中,我制作了很多列表(树状结构,每个节点可以有很多孩子),其中一些节点没有任何子节点,因为我的应用程序速度很快,但也使用了很多内存决定使用我可以指定容量的构造函数,并将其设置为1。

现在奇怪的是,当我使用容量为1时,内存使用量比使用默认构造函数时高出约15%。它不能因为更好地适应4,因为倍增将是1,2,4。那么为什么这会额外增加内存使用量呢?作为一项额外的测试,我尝试从容量为4开始。再一次,内存使用率比没有指定容量时高出15%。

现在这确实不是问题,但令我困扰的是,我多年来使用的一个非常简单的数据结构有一些我还不知道的额外逻辑。有没有人知道List在这方面的内部运作?

1 个答案:

答案 0 :(得分:2)

那是因为如果你使用默认构造函数,内部存储数组被设置为一个空数组,但是如果你使用具有set size的构造函数,则会立即设置正确大小的数组,而不是在第一次调用时生成添加。

你可以使用像JustDecompile这样的反编译器来看到这个:

public List(int capacity)
{
    if (capacity < 0)
    {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
    }
    this._items = new T[capacity];
}

public List()
{
    this._items = List<T>._emptyArray;
}

如果查看Add函数,则调用EnsureCapacity,如果需要,将扩大内部存储阵列。显然,如果数组最初设置为空数组,则第一个添加将创建默认大小数组。