在Delphi中使用动态数组记录与TList <TMyRecord>有什么优缺点?

Kro*_*ica 7 arrays delphi storage record

这是一个理论问题,旨在生成Delphi中不同数据存储方式的优缺点查找列表.

假设我们有一个记录:

type
  TMyRecord = record 
    X,Y,Z: Single; 
    IsValid: Boolean; 
  end;
Run Code Online (Sandbox Code Playgroud)

存储此类记录数组的基本选项是:

  • array of TMyRecord;
  • TListgetter/setter的自定义后代
  • TList<TMyRecord>;

我特别感兴趣的是#1 vs#3比较,这些差异有多大,特别是在性能方面.

Fr0*_*0sT 12

TList<T> 优点:

  • 数组没有用于添加/插入/删除/排序/搜索的有用方法,TList没有.
  • TList具有Notify方法,可以覆盖该方法以对项目添加/删除执行某些自定义操作.

TList<T> 缺点:

  • TList<T>[i]实际上返回其元素的副本.所以你不能写出类似的东西TList<TMyRec>[idx].SomeField := foo.相反,您必须使用临时变量.数组显然允许这样的表达. David Heffernan提到TList<T>.List消除了这个缺点; 然而,它只出现在XE3中
  • TList是一个对象,不需要时应该在程序结束时删除.
  • System.Generics.Collections单元可以为之前未使用System.Classes单元的项目添加大量二进制大小.

对于我自己,我写了一个TRecordList<T>类,它将项目作为指针操作(就像经典的TList一样).

  • `TList <T> .List`是dyn数组,因此不需要副本.在性能方面,dyn数组没有优势. (2认同)

Dav*_*nan 6

TL;博士

  • 指向独立内存块的指针列表对缓存不友好,应该避免.
  • 动态数组具有与之相同的性能特征TList<T>.
  • TList<T> 为动态数组无法承受的程序员提供了许多便利.

实现TList<T>是项目存储在动态数组中.因此,TList<T>和之间基本上没有性能差异TArray<T>.

当然,动态数组使您可以直接访问元素而无需复制.如果重要,您可以使用相同的List属性TList<T>.事实上,该属性意味着在性能方面,至少TList<T>是普通动态数组的匹配.

除了性能之外,使用TList<T>还可以为原始动态数组提供各种便利.我不需要列举这些便利.您可以从公共方法和属性列表中清楚地看到它们.

由于性能对您很重要,因此您应该使用问题中的代码解决实际性能问题.即你打包记录的事实.这将导致记录的大多数情况不一致.这具有可怕的性能影响.如果您关心性能,则会对齐结构.

您的中间选项,指针列表并不值得考虑.它可能会在整个地址空间中分散内存,并且对缓存不友好.