是否有更快的TList实现?

时间:2010-04-06 12:21:11

标签: delphi optimization

我的应用程序大量使用TList,所以我想知道是否有更快或针对特定用例优化的替代实现。

我知道RtlVCLOptimize.pas 2.77,它优化了几种TList方法的实现。

但我想知道那里还有什么。我也不要求它是TList后代,我只需要TList功能而不管它是如何实现的。

考虑到TList提供的相当基本的功能,完全有可能没有太大的改进空间,但仍然想验证这一点,因此这个问题。

编辑:在我的特定用例中,没有列表被排序。有很多列表,其中包含了不同数量的元素。我确实用自己的类替换了TList,以便记录添加/删除调用的数量和元素的数量。它报告(所有列表的toatal):

ListAdd = 15766012; ListRemove = 10630000; ListCount = 5136012

我还可以找出单个列表中元素数量最多的是什么。

我没有特别的问题,我只是想知道是否有办法让它更快,因为这些数字甚至会有很小的改进。

4 个答案:

答案 0 :(得分:8)

我对TList了解的最大瓶颈之一是大型列表中的删除/提取。删除项目[0]比删除项目[计数-1]慢得多,因为它后面的内存移动。

例如,在包含65536个元素的列表中:

while list.Count > 0 do List.Delete(0) //Takes 2 mins to complete

for I := List.Count-1 downto 0 do List.Delete(I) //Takes less than 1 sec

因此,如果你有一个拥有数百万个元素的TList,那么删除一个低索引项可能在性能上是昂贵的。另外,考虑到列表未排序会导致在其中找到元素的速度非常慢。 IndexOf在大型列表上非常慢。您可能需要考虑保持列表排序。

另外,考虑到您的项目数量可能非常大,您可能需要考虑使用TList列表来存储元素,这将有助于减少我已经提到的删除/提取开销。

答案 1 :(得分:7)

看起来你做了很多补充。我不知道有多少列表已经传播,但如果您的个人列表变得非常大,您可能希望实现一个增长更快的列表。

查看TList.Grow,当您尝试将项目添加到其所有数组元素都在使用的列表中时调用该项目,您将看到它增长了25%。这是为了将内存使用降低到合理的水平。但是,如果您需要非常大的列表,请创建自己的后代类并覆盖Grow,以便在第二行中,而不是Delta := FCapacity div 4,它会显示Delta := FCapacity。这使得您的列表每次增长两倍,这意味着更少的reallocs和更少的副本。

但可能会杀死你的是所有那些删除电话。删除必须找到该项才能删除它,这涉及到对IndexOf的调用,这是对整个数组的线性扫描。如果你有一个很大的列表并且你做了很多删除,那就会破坏你的表现。

您使用这些列表的是什么,尤其是大型列表?根据您对它们的处理方式,可能会有更好的数据结构。

答案 2 :(得分:6)

您使用的是通知程序吗?如果没有,请创建自己的TList实现。由于Notify过程,TList.Clear(在销毁时调用)是O(n)操作。 TList.Clear方法调用SetCount,SetCount又为其包含的所有项调用Delete,因此将为每个删除的项调用Notify过程。如果不需要覆盖Notify方法,则可以调整SetCount过程以不调用Delete。这样可以节省15.766.012 - 10.630.000 = 5.136.012删除电话的时间。

注意:正如Mason Wheeler所建议的那样,您获得的性能提升永远不会像排序列表和优化删除程序所获得的性能提升那么大。除非您的列表包含非常少量的项目,并且比较功能需要花费大量时间。

答案 3 :(得分:1)

最快的数据结构通常不是数据结构,而是一个仅在需要时提取数据的模拟,就像Virtual Treeview一样。也许你可以写一些TVirtualList来调用适当的函数来在请求元素时收集所需的数据。