Каковы плюсы и минусы использования динамического массива записей против TList в Delphi?
это теоретический вопрос, предназначенный для создания списка плюсов и минусов различных способов хранения данных в Delphi.
допустим, у нас есть запись:
type
TMyRecord = record
X,Y,Z: Single;
IsValid: Boolean;
end;
основными вариантами хранения массива таких записей являются:
array of TMyRecord;
- пользовательские потомок
TList
С геттер/сеттер TList<TMyRecord>;
меня особенно интересует сравнение #1 vs #3, Сколько стоит разница между ними, особенно с точки зрения производительности.
2 ответов
TList<T>
плюсы:
- массив не имеет полезных методов для добавления / вставки / удаления / сортировки / поиска, TList делает.
- TList имеет метод Notify, который может быть переопределен для выполнения некоторых пользовательских действий по добавлению/удалению элемента.
TList<T>
плюсы:
-
TList<T>[i]
на самом деле возвращает скопировать ее элемент. Поэтому вы не можете написать что-то вродеTList<TMyRec>[idx].SomeField := foo
. Вместо этого, вы должны используйте временную переменную. Array явно допускает такое выражение. Дэвид Хеффернан упомянулTList<T>.List
что устраняет этот недостаток; однако он появился только в XE3 - TList-это объект, который должен быть удален
на финише программыкогда не нужен.
tl; dr
- список указателей на независимые блоки памяти является недружественным для кэша и его следует избегать.
- динамические массивы имеют те же характеристики производительности, что и
TList<T>
. -
TList<T>
предлагает много удобств программисту, которые динамические массивы не позволяют.
реализация TList<T>
заключается в том, что элементы хранятся в динамическом массиве. Так есть по существу нет различий в производительности между TList<T>
и TArray<T>
.
конечно, динамический массив дает вам прямой доступ к элементам без создания копий. Вы можете сделать то же самое, используя List
собственность TList<T>
Если это имеет значение. На самом деле это свойство означает, что с точки зрения производительности по крайней мере TList<T>
соответствует простому динамическому массиву.
за пределами производительности, используя TList<T>
дает вам все виды услуг по сырым динамические матрица. Мне не нужно перечислять эти удобства. Вы можете ясно видеть их из списка общедоступных методов и свойств.
поскольку производительность важна для вас, вы должны решить реальную проблему производительности с кодом в вопросе. А именно тот факт, что вы упаковали свой рекорд. Что приведет к большинству экземпляров записи несоосность. И это имеет ужасные последствия для производительности. Если вы заботитесь о производительности, вы выровняете структуры.
ваш средний вариант, список указателей на самом деле не стоит рассматривать. Скорее всего, он разбросает память по всему адресному пространству и будет недружелюбен к кэшу.