What are the pros and cons of using dynamic array of records vs. TList<TMyRecord> in Delphi? What are the pros and cons of using dynamic array of records vs. TList<TMyRecord> in Delphi? arrays arrays

What are the pros and cons of using dynamic array of records vs. TList<TMyRecord> in Delphi?


TList<T> pros:

  • Array doesn't have useful methods for adding/inserting/deleting/sorting/searching, TList does.
  • TList has Notify method that could be overriden to perform some custom actions on item addition/deletion.

TList<T> cons:

  • TList<T>[i] actually returns a copy of its element. So you can't write something like TList<TMyRec>[idx].SomeField := foo. Instead, you have to use temporary variable. Array obviously allows such expression.David Heffernan mentioned TList<T>.List which eliminates this drawback; however, it appeared only in XE3
  • TList is an object which should be deleted at program finish when not needed.
  • System.Generics.Collections unit could add plenty of binary size to a project that wasn't using System.Classes unit before.

For myself I wrote TRecordList<T> class which operates items as pointers (like classic TList does).


tl;dr

  • A list of pointers to independent blocks of memory is unfriendly to the cache and should be avoided.
  • Dynamic arrays have the same performance characteristics as TList<T>.
  • TList<T> offers many conveniences to the programmer that dynamic arrays do not afford.

The implementation of TList<T> is that the items are stored in a dynamic array. So there are essentially no performance differences between TList<T> and TArray<T>.

Of course, the dynamic array gives you direct access to the elements without making copies. You can do the same using the List property of TList<T> if that matters. In fact that property means that in performance terms at least TList<T> is a match for a plain dynamic array.

Beyond performance, using TList<T> gives you all sorts of convenience over a raw dynamic array. I don't need to enumerate these conveniences. You can see them clearly from the list of public methods and properties.

Since performance is important to you, you should tackle the real performance issue with the code in the question. Namely the fact that you packed your record. That will lead to the majority of instances of the record being mis-aligned. And that has dire performance implications. If you care about performance, you will align structures.

Your middle option, a list of pointers is not really worth considering. It will likely scatter memory all over the address space and be unfriendly to the cache.