.Net 2.0 - How efficient are Generic Lists?
我正在创建一个应用程序,该应用程序将负载的用户数据负载保存在内存中,并且大部分将其全部保存在List < T >结构中(以及某些需要查询的Dictionary 我想知道...
列表的效率如何? 有没有更有效的方法? 字典只是HashTables,对不对?还是它们的数据结构效率较低? 我想使用数组,但是我一直都有一个典型的问题,就是一直在它们中添加和删除东西,因此不得不增加/缩小它们会很痛苦。 有什么想法/建议吗? 编辑:我知道我的基本数据结构101,为什么链表更适合添加/删除,而哈希表更适合随机访问。 我最担心的是.Net的独特性。例如,这些结构各自浪费多少内存。并且浪费时间初始化/杀死它们。 例如,如果要花很多时间来实例化/ GC一个列表,但清除它的时间不多,也许我应该保留一小部分列表等待我,然后清除它们并将它们发送回该池中完成后,而不是简单地取消引用它们。 或者,如果哈希表的访问速度更快但浪费大量内存,则我可能更喜欢使用列表并遍历它们,以减少项目数量。
而且我也非常想关注内存使用情况,因为我的应用程序占用大量内存(请像memcached一样)... 如果必须将大量数据保存在内存中,也许您应该考虑使用某种类型的内存数据库, 如果您真的想查看如何实现List <>和Dictionary <,>的所有细节,请使用非常有用的.NET Reflector。 另请参见出色的C5通用集合库的文档,该文档具有BCL缺少的许多集合类型的良好实现。 由于链接列表的性质,LinkedList对象将花费更少的时间添加和删除。添加元素时,不必像普通列表那样调整数组的大小。除了该改进之外,我怀疑LinkedList的性能与普通List大致相同。 在Wikipedia上查看此内容:链接列表与数组 如果您需要高效地在列表中的随机位置插入或删除列表,则可以使用LinkedList数据结构-MSDN文章提供了详细信息。显然,作为链表的随机访问效率不高。 列表内部使用数组,而字典使用哈希表。 它们比旧的非泛型类ArrayList和HashTable更快,因为您无需花费将所有内容与对象进行转换(装箱,拆箱和类型检查)的成本,并且因为MS比旧类更好地对其进行了优化。 列表是位于其下方的数组,因此添加项目(除非在项目末尾)对性能的影响将非常昂贵。 否则,它们将基本上与数组一样快。 我认为两步操作可能会过大。加上进程间的通信可能会有些缓慢(尽管我从未尝试过这种事情,所以请以我的看法为准)。我在一个数据驱动的应用程序上工作,每个数据单元很小,但是在任何给定时间我们可能有十亿个数据单元。我们使用的方法基本上是:
换句话说,这是一种自制缓存方案。好处是您可以精确地控制内存中的数据,而如果依赖于OS分页方案,则无法控制。如果某个常用变量最终与页面上的数据混合在一起,则该页面将被反复打入并阻止其进入磁盘。如果您在应用程序中设计了一些数据请求将比其他数据花费更长的时间的住宿,那么这将很好地工作。特别是如果您知道提前需要什么块(我们不需要)。 请记住,.NET应用程序中的所有内容都必须在2 GB的内存内,并且由于GC的工作方式和应用程序的开销,实际上您的工作量可能要少一些。 要监视您的堆到底是什么以及正在分配谁,请使用CLR分析器:http://www.microsoft.com/downloads/details.aspx?familyid=86ce6052-d7f4-4aeb-9b7a-94635beebdda&displaylang=en 如果您担心内存使用情况,真正的关键是将阵列存储在磁盘上,然后将所需的部分仅映射到内存中。 关键是使用FILE_FLAG_NO_BUFFERING并始终精确地读/写一个扇区的数据。 在出现一些性能问题并且探查器表明确实如此之前,我不会动动手指。然后,您将有一个明确的问题需要解决,并且会容易得多。 .Net列表不使用链接列表。它是一个数组,默认情况下以4个位置开头,我认为添加内容时其大小会增加一倍。因此,性能可能会有所不同,具体取决于您的使用方式。 如果您使用VS 2008,请先运行探查器,然后再深入研究。当我们开始真正地查看我们在浪费时间的时候,并不需要花费很长时间就可以得出结论,对链表的细节进行辩论实际上并不重要。 |