What are the pros and cons of using a dynamic array of records against TList <TMyRecord> in Delphi?
This is a theoretical question designed to create a search list of the pros and cons of various ways of storing data in Delphi.
Say we have a record:
type TMyRecord = record X,Y,Z: Single; IsValid: Boolean; end; The main parameters for storing an array of such records:
array of TMyRecord;- custom
TListdescendant with getter / setter TList<TMyRecord>;
I am particularly interested in comparing No. 1 and No. 3, how much the difference is between them, especially in terms of performance.
TList<T> pros:
- The array has no useful methods for adding / inserting / deleting / sorting / searching, TList does.
- TList has a Notify method, which can be overridden to perform some user actions when adding / removing an item.
TList<T> Cons:
TList<T>[i]actually returns a copy of its element. Therefore, you cannot write something likeTList<TMyRec>[idx].SomeField := foo. Instead, you should use a temporary variable. The array obviously admits such an expression. David Heffernan mentionedTList<T>.List, which addresses this flaw; however, it only appeared in XE3- A TList is an object that should be deleted
when the program terminateswhen it is not required. - The System.Generics.Collections module can add a lot of binary size to a project that has not previously used System.Classes.
For myself, I wrote a class TRecordList<T> , which controls elements as pointers (for example, the classic TList).
TL; DR
- The list of pointers to independent memory blocks is cache unfriendly and should be avoided.
- Dynamic arrays have the same performance characteristics as
TList<T>. TList<T>offers many amenities to the programmer who do not provide dynamic arrays.
The implementation of TList<T> is that the elements are stored in a dynamic array. Thus, there is essentially no performance difference between TList<T> and TArray<T> .
Of course, a dynamic array gives you direct access to elements without copying. You can do the same using the List property TList<T> , if that matters. In fact, this property means that under performance conditions, at least TList<T> is a match for a simple dynamic array.
In addition to performance, using TList<T> gives you all sorts of convenience over a raw dynamic array. I do not need to list these amenities. You can clearly see them from the list of public methods and properties.
Since performance is important to you, you must solve the real performance problem with the code in question. Namely, the fact that you have collected your record. This will result in most cases where the record is misaligned. And this has serious performance implications. If you care about performance, you will align the structures.
Your average option, a list of pointers is not really worth considering. It will probably scatter memory across the entire address space and be cache-unfriendly.