C# 嵌套字典大小增长

C# 嵌套字典大小增长,c#,.net,dictionary,size,C#,.net,Dictionary,Size,我有一个简单的字典对象,当我在其中填充1000万个条目时,它会占用500 MB的空间。但是当我使用嵌套字典字典时,同样的1000万个条目占用了2.5 GB的空间。内部词典只填写了一个条目 有人能帮助解释一下.net中的字典是如何分配内存的,以及它的大小是如何增长的吗?如果你看一下字典的定义,你会发现它有很多成员,所以即使是空的字典也会比其中的键和元素占用更多的空间 如果您查看它是如何初始化的,您将遇到以下函数 private void Initialize(int capacity) {

我有一个简单的
字典
对象,当我在其中填充1000万个条目时,它会占用500 MB的空间。但是当我使用嵌套字典
字典
时,同样的1000万个条目占用了2.5 GB的空间。内部词典只填写了一个条目


有人能帮助解释一下.net中的字典是如何分配内存的,以及它的大小是如何增长的吗?

如果你看一下字典的定义,你会发现它有很多成员,所以即使是空的字典也会比其中的键和元素占用更多的空间

如果您查看它是如何初始化的,您将遇到以下函数

private void Initialize(int capacity)
{
    int prime = HashHelpers.GetPrime(capacity);
    this.buckets = new int[prime];
    for (int i = 0; i < this.buckets.Length; i++)
    {
        this.buckets[i] = -1;
    }

    this.entries = new Entry<TKey, TValue>[prime];
    this.freeList = -1;
}
添加元素时,如果有足够的空间添加元素,则字典的大小保持不变。如果没有,则使用以下函数扩展字典:

public static int ExpandPrime(int oldSize)
{
    int min = 2 * oldSize;
    if ((min > 0x7feffffd) && (0x7feffffd > oldSize))
    {
         return 0x7feffffd;
    }

    return GetPrime(min);
}
GetPrime
的实现如下:

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static int GetPrime(int min)
{
    if (min < 0)
    {
        throw new ArgumentException(Environment.GetResourceString("Arg_HTCapacityOverflow"));
    }

    for (int i = 0; i < primes.Length; i++)
    {
         int num2 = primes[i];
         if (num2 >= min)
         {
             return num2;
         }
    }

    for (int j = min | 1; j < 0x7fffffff; j += 2)
    {
        if (IsPrime(j) && (((j - 1) % 0x65) != 0))
        {
             return j;
        }
    }

    return min;
}

您是如何测量对象的大小的?我使用进程内存消耗作为大小的指标,因为源代码中没有其他内容。这对我来说似乎非常合理,它意味着一个
字典(有一个条目)比一个简单的
长的
大5倍。。。考虑字典有其他内部字段(例如元素的数量等)…
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static int GetPrime(int min)
{
    if (min < 0)
    {
        throw new ArgumentException(Environment.GetResourceString("Arg_HTCapacityOverflow"));
    }

    for (int i = 0; i < primes.Length; i++)
    {
         int num2 = primes[i];
         if (num2 >= min)
         {
             return num2;
         }
    }

    for (int j = min | 1; j < 0x7fffffff; j += 2)
    {
        if (IsPrime(j) && (((j - 1) % 0x65) != 0))
        {
             return j;
        }
    }

    return min;
}
static HashHelpers()
{
    primes = new int[] { 
    3, 7, 11, 0x11, 0x17, 0x1d, 0x25, 0x2f, 0x3b, 0x47, 0x59, 0x6b, 0x83, 0xa3, 0xc5, 0xef, 
    0x125, 0x161, 0x1af, 0x209, 0x277, 0x2f9, 0x397, 0x44f, 0x52f, 0x63d, 0x78b, 0x91d, 0xaf1, 0xd2b, 0xfd1, 0x12fd, 
   0x16cf, 0x1b65, 0x20e3, 0x2777, 0x2f6f, 0x38ff, 0x446f, 0x521f, 0x628d, 0x7655, 0x8e01, 0xaa6b, 0xcc89, 0xf583, 0x126a7, 0x1619b, 
   0x1a857, 0x1fd3b, 0x26315, 0x2dd67, 0x3701b, 0x42023, 0x4f361, 0x5f0ed, 0x72125, 0x88e31, 0xa443b, 0xc51eb, 0xec8c1, 0x11bdbf, 0x154a3f, 0x198c4f, 
   0x1ea867, 0x24ca19, 0x2c25c1, 0x34fa1b, 0x3f928f, 0x4c4987, 0x5b8b6f, 0x6dda89
 };
}