Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 初始容量字典_.net_Vb.net - Fatal编程技术网

.net 初始容量字典

.net 初始容量字典,.net,vb.net,.net,Vb.net,我了解到,如果可以估计字典的大小,那么使用初始容量初始化字典可能会带来更好的性能 Dim MyDataTable As New DataTable 'Fill MyDataTable from Database Dim CapacityEstimate As integer = MyDataTable.Rows.Count Dim MyDictionary As New Dictionary(Of String, MyObjectType)(CapacityEstimate) 'Fill

我了解到,如果可以估计字典的大小,那么使用初始容量初始化字典可能会带来更好的性能

Dim MyDataTable As New DataTable

'Fill MyDataTable from Database

Dim CapacityEstimate As integer = MyDataTable.Rows.Count
Dim MyDictionary As New Dictionary(Of String, MyObjectType)(CapacityEstimate)

'Fill the Dictionary independent of data table
CapacityEstimate变量只是字典应该保存的键/值对数量的估计(通常在2500到7000之间)。因此,如果我估计它是4000个,最终有4010个对象(我可能会超过或低于,不确定),那么字典会使用大量内存来调整大小,因为其中已经有很多键/值对。这是一个好的解决方案,还是我最好不要用初始容量初始化它。谢谢

编辑:相关但不相同-

如果字典中已经有那么多的键/值对,它会使用大量内存来调整大小吗

只有超出估计容量时,字典才会“调整大小”

Dim MyDataTable As New DataTable

'Fill MyDataTable from Database

Dim CapacityEstimate As integer = MyDataTable.Rows.Count
Dim MyDictionary As New Dictionary(Of String, MyObjectType)(CapacityEstimate)

'Fill the Dictionary independent of data table
将为您估计的项目数保留内存-这将在
字典的构造函数中发生

现在,容量和实际大小之间存在差异。容量是指字典在不调整内部存储大小的情况下可以容纳多少项。大小是实际存储在字典中的项目数(即添加到字典中的项目)

如果字典中已经有那么多的键/值对,它会使用大量内存来调整大小吗

只有超出估计容量时,字典才会“调整大小”

Dim MyDataTable As New DataTable

'Fill MyDataTable from Database

Dim CapacityEstimate As integer = MyDataTable.Rows.Count
Dim MyDictionary As New Dictionary(Of String, MyObjectType)(CapacityEstimate)

'Fill the Dictionary independent of data table
将为您估计的项目数保留内存-这将在
字典的构造函数中发生


现在,容量和实际大小之间存在差异。容量是指字典在不调整内部存储大小的情况下可以容纳多少项。大小是实际存储在字典中的项目数(即添加到字典中的项目)。

这是个好问题。我没有到处找,但奥德的回答对我来说很好

但是,让我们在其上运行一个概念性的微观基准测试:

        Dictionary<string, int> FixedCapacity = new Dictionary<string, int>(4000);
        Dictionary<string, int> NotFixedCapacity = new Dictionary<string, int>();

        Stopwatch stopWatch = new Stopwatch();

        stopWatch.Start();

        for (int i = 0; i < 5000; i++)
        {
            FixedCapacity.Add(i.ToString(), i);
        }

        stopWatch.Stop();

        Console.WriteLine(string.Format("Fixed initial capacity: {0} ms", stopWatch.ElapsedMilliseconds));

        stopWatch.Reset();

        stopWatch.Start();

        for (int i = 0; i < 5000; i++)
        {
            NotFixedCapacity.Add(i.ToString(), i);
        }

        stopWatch.Stop();

        Console.WriteLine(string.Format("Not Fixed initial capacity: {0} ms", stopWatch.ElapsedMilliseconds));

        Console.ReadLine();
这是另一个好答案,IMO=)


免责声明:不,这不是一个完整的基准测试过程,我只是在一台机器上测量框架的“默认”行为。我已经手动运行了好几次,得到了相同的结果,即使它不在循环中。如果您有更好的基准测试工具,请测试它并将结果粘贴到此处。

这是一个好问题。我没有到处找,但奥德的回答对我来说很好

但是,让我们在其上运行一个概念性的微观基准测试:

        Dictionary<string, int> FixedCapacity = new Dictionary<string, int>(4000);
        Dictionary<string, int> NotFixedCapacity = new Dictionary<string, int>();

        Stopwatch stopWatch = new Stopwatch();

        stopWatch.Start();

        for (int i = 0; i < 5000; i++)
        {
            FixedCapacity.Add(i.ToString(), i);
        }

        stopWatch.Stop();

        Console.WriteLine(string.Format("Fixed initial capacity: {0} ms", stopWatch.ElapsedMilliseconds));

        stopWatch.Reset();

        stopWatch.Start();

        for (int i = 0; i < 5000; i++)
        {
            NotFixedCapacity.Add(i.ToString(), i);
        }

        stopWatch.Stop();

        Console.WriteLine(string.Format("Not Fixed initial capacity: {0} ms", stopWatch.ElapsedMilliseconds));

        Console.ReadLine();
这是另一个好答案,IMO=)


免责声明:不,这不是一个完整的基准测试过程,我只是在一台机器上测量框架的“默认”行为。我已经手动运行了好几次,得到了相同的结果,即使它不在循环中。如果您有更好的基准测试工具,请测试它并将结果粘贴到此处。

不要担心小问题。像这样的字典不会占用很多内存,所以让它自己调整大小也不会占用很多内存。真正的存储是键和数据的对象,字典只包含对它们的引用。32位模式下每个条目8字节,因此只有4000 x 8+一些开销=32 KB

此外,您传递的容量用于计算字典中哈希桶的数量。它始终是一个素数,等于或大于指定的容量。质数从该数组中选取(从参考源复制):

如果你超过4000,那么你将得到4049个桶,下一个最大的素数。所以超过4010不会有什么不同。如果它确实需要调整大小,那么它的容量将加倍。因此,一次调整大小将产生8419个桶,远远超过您的最大估计值。调整大小也不是很昂贵,只需几微秒。这就是为什么安德烈看不出有什么不同


这是正确的方法,而不是推理。量。任何人都可以测量。

不要担心小东西。像这样的字典不会占用很多内存,所以让它自己调整大小也不会占用很多内存。真正的存储是键和数据的对象,字典只包含对它们的引用。32位模式下每个条目8字节,因此只有4000 x 8+一些开销=32 KB

此外,您传递的容量用于计算字典中哈希桶的数量。它始终是一个素数,等于或大于指定的容量。质数从该数组中选取(从参考源复制):

如果你超过4000,那么你将得到4049个桶,下一个最大的素数。所以超过4010不会有什么不同。如果它确实需要调整大小,那么它的容量将加倍。因此,一次调整大小将产生8419个桶,远远超过您的最大估计值。调整大小也不是很昂贵,只需几微秒。这就是为什么安德烈看不出有什么不同


这是正确的方法,而不是推理。量。任何人都可以测量。

我知道这可能太晚了,但无论如何,这可能对任何阅读本文的人都有价值。最好将容量设置为某个已知值的原因是为了防止重新分配。在一个高度繁忙、全天候的服务/应用程序中,内存利用率非常高/极端,您可能希望通过将容量设置为已知大小或某个平均/估计大小来防止内存重新分配,从而避免增加额外的压力

在这种情况下,内存重新分配会在内存空间中产生“(小)洞”,从而导致内存碎片。有一段时间,即使内存仍然很大,因为碎片太多,那么你的应用程序可能会遇到“内存不足”的情况

在.NET4.5.1之前,这一观察结果是正确的,我相信这是我最后一次测试/观察这一点的时候。如果较新的框架版本具有更好的垃圾收集器