.Net 2.0-泛型列表的效率如何?

时间:2020-03-05 18:44:41  来源:igfitidea点击:

我正在创建一个应用程序,该应用程序将用户数据的负载保存在内存中,并且大部分将它们全部保存在List <T>结构中(以及某些需要查询的Dictionary <T,T>)。

我想知道...

列表的效率如何?
我每个人要获得多少内存开销? (也就是说,除了它们包含的对象将占用的内存空间之外)
每次提出新的罚款,我要支付多少罚款?

有没有更有效的方法?

字典只是HashTables,对不对?还是它们的数据结构效率较低?

我想使用Array,但是我一直都有一个典型的问题,就是一直在它们中添加和删除东西,因此必须增大/缩小它们会很痛苦。

有什么想法/建议吗?

编辑:我知道我的基本数据结构101,为什么链表更适合添加/删除,而哈希表更适合随机访问。

我最担心的是.Net的独特性。例如,这些结构各自浪费多少内存。并且浪费时间初始化/杀死它们。

例如,如果要花很多时间来实例化/ GC一个列表,但清除它的时间不多,也许我应该保留一些列表池等待我,然后清除它们并将它们发送回该池完成后,而不是简单地取消引用它们。

或者,如果哈希表的访问速度更快但浪费大量内存,则我可能更喜欢使用列表并遍历它们,以减少项目数量。

而且我也非常想专注于内存使用,因为我的应用程序占用大量内存(请像memcached一样)...
有谁知道我在哪里可以找到这样的信息?

解决方案

回答

列表是位于其下方的数组,因此添加项目(除非在项目末尾)对性能的影响将非常高昂。

否则,它们将基本上与数组一样快。

回答

列表内部使用数组,而字典使用哈希表。

它们比旧的非泛型类ArrayList和HashTable更快,因为我们无需花费将所有内容与对象进行转换(装箱,拆箱和类型检查)的费用,并且因为MS比旧类更好地对其进行了优化。

回答

如果必须将大量数据保存在内存中,也许我们应该考虑使用某种类型的内存数据库,

回答

如果我们需要高效地在列表中的随机位置插入或者删除列表,则MSDN文章提供了LinkedList数据结构的详细信息。显然,作为链表的随机访问效率不高。

回答

由于链接列表的性质,LinkedList对象将花费更少的时间添加和删除。添加元素时,不必像普通列表一样调整数组的大小。除了该改进之外,我怀疑LinkedList的性能与普通List大致相同。

在Wikipedia上查看此内容:链接列表与数组

回答

如果我们担心内存的使用,真正的关键是将阵列存储在磁盘上,然后将所需的部分仅映射到内存中。

关键是要使用FILE_FLAG_NO_BUFFERING并始终精确地读/写一个扇区的数据。

回答

.Net列表不使用链接列表。它是一个数组,默认情况下以4个位置开头,我认为添加内容时其大小会增加一倍。因此,性能可能会有所不同,具体取决于使用方式。

如果我们使用的是VS 2008,请在深入了解此问题之前运行分析器。当我们开始真正地查看我们在浪费时间的地方时,并不需要花费很长时间就可以得出结论,对链表的细微讨论实际上并不重要。

回答

我认为两步操作可能会过大。加上进程间的通信可能会有些慢(尽管我从未尝试过这种事情,所以请以我的看法为准)。我在一个数据驱动的应用程序上工作,每个数据单元很小,但是在任何给定时间我们可能有十亿个数据单元。我们使用的方法基本上是:

  • 一切都驻留在磁盘上,无论如何
  • 数据被阻塞为"块";每个块都知道上次访问的时间
  • 需要时将块从磁盘拖动到内存中
  • 低优先级线程监视内存使用情况并删除最近最少使用的内容

换句话说,这是一种自制缓存方案。好处是我们可以精确地控制内存中的数据,而如果依赖于OS分页方案,则无法控制。如果某个常用变量最终与页面上的数据混合在一起,则该页面将被反复打入并阻止其进入磁盘。如果我们在应用程序中设计了一些数据请求将比另一些数据请求花费更长的时间的住宿,那么这将很好地工作。特别是如果我们知道提前需要什么块(我们不需要)。

请记住,.NET应用程序中的所有内容都必须在2 GB的内存内,并且由于GC的工作方式和应用程序的开销,我们实际上所使用的内存可能要少一些。

若要监视堆到底是什么以及正在分配谁,请使用CLR分析器:http://www.microsoft.com/downloads/details.aspx?familyid=86ce6052-d7f4-4aeb-9b7a-94635beebdda&displaylang=en

回答

如果我们真的想查看有关如何实现List <>和Dictionary <,>的所有细节,请使用非常有用的.NET Reflector。

另请参见出色的C5通用集合库的文档,该文档具有BCL缺少的许多集合类型的良好实现。

回答

在出现一些性能问题并且探查器表明确实如此之前,我不会动动手指。然后,我们将有一个明确的问题要解决,并且会容易得多。