.net与容量相关的通用列表优化

本文关键字:列表 优化 容量 net | 更新日期: 2023-09-27 17:55:04

我目前正在使用一个应用程序,将做以下工作。

// Initialize a list: 
myList = new List<aPoint>;
while(WeHaveMoreData)
   myList->Add(ReturnNext1000Points());

我无法从一开始就知道列表的总大小。据我所知,List<>是处理这么多数据传入(可能超过500k条记录)的最佳方式。

我想知道我是否应该处理列表的容量(给它初始值,或者增加上限,如果它需要它)?

我如何接近优化这样一个过程?

.net与容量相关的通用列表优化

如果您有总记录的近似值,您可以设置列表的容量,否则让它增长。它是非常优化的,只要确保你不会耗尽内存。另一种方法是使用惰性迭代器,它不会将整个列表加载到内存中:

public IEnumerable<aPoint> GetPoints()
{
    while(WeHaveMoreData)
    {
        yield return new aPoint();
    }
}

只有当你开始迭代时,记录才会开始被获取,一条一条地被立即释放:

foreach (var point in GetPoints())
{
    /// TODO: do something with the point
}

第一条规则:过早优化是万恶之源。如果性能不是问题,就让它保持原样。您应该尝试将列表的初始大小设置为大约AverageExpectedSize/0.7

我也认为你不能优化它。我猜你在某些特定情况下可以做得更好,所以我有一个问题-你之后如何处理这些数据?还有——你想优化内存还是速度?

一个典型的列表实现每次都会以2倍的速度增长容量,所以也许你可以通过拥有一个List<aPoint[]>来节省一些空间,它将拥有更少的元素,所以你不太可能有几个100k的空闲容量。但这只在内存即将耗尽时才会有影响——在任何情况下,数据本身都可能花费更多的内存。

一般来说,如果你不知道+/- 20%以内的元素数量,那么你可能应该盲目地添加到List中,而不是猜测容量。

List与数组的不同之处在于,当容量达到极限时,需要进行加法运算。请记住,一旦您超出了列表的容量,它的容量将翻倍。例如,如果列表的当前容量为128个元素,而您添加了一个元素,使其成为129个元素,那么列表的容量将调整为256个元素。然后对于接下来的128个添加,你根本不调整列表的大小。一旦到达257,它将翻倍到512,并重复这个过程。

因此你将有O(log(n))个大小调整到你的列表