Могу ли я добавить другой выбор в ваш список?
Если вы не используете какую-либо функцию наследования для данных в TAtom
, вы можете использовать record
вместо class
. Каждый экземпляр класса должен быть размещен в памяти, заполнен нулями и инициализирован индивидуально. Getmem/Freemem
всегда стоит, а фрагментация памяти увеличится.
Предварительно выделенная динамическая array of record
будет быстрее, чем отдельные экземпляры классов для добавления. И данные лучше подойдут для кэша CPU L1 / L2.
Для вставки и удаления массив таких записей будет медленнее, чем TList
, если у вас огромное количество элементов, потому что будет больше данных для удаления / вставки (TList/TObjectList
оба поддерживают только список указатели). Для еще более быстрой вставки / удаления лучше использовать связанный список.
Из-за внутреннего уведомления в механизме TList/TObjectList
есть некоторые издержки. механизм И свойство GetItem()
может быть немного медленнее (из-за проверки диапазона), чем напрямую использовать динамический массив.
Но с нашей оболочкой TDynArray вы можете придерживаться динамического массива и при этом иметь хорошую производительность, функции предварительного выделения и TList
-подобные методы. И даже больше доступных методов, таких как SaveToStream, Slice, Reverse
, сортировка по внешним индексам и тому подобное ...
type
TAtom = record // could be 'packed record' to save memory (but loose perf)
ElementZ: Integer;
X, Y, Z: Extended;
other variables: other types;
// TDynArray also handle complex (e.g. string) types here
end;
TAtoms = array of TAtom;
var Atom: TAtom;
AtomArray: TAtoms;
AtomCount: integer;
Atoms: TDynArray;
begin
Atoms.Init(TypeInfo(TAtoms),AtomArray,@AtomCount);
Atoms.Capacity := 10000; // pre-allocate array = same as SetLength(AtomArray,10000)
for i := 1 to 10000 do begin
A.ElementZ := Random(1000);
A.X := Random;
A.Y := Ramdom;
A.Z := Random;
// set other fields
Atoms.Add(A); // fast adding of A properties
end;
// you have TList-like methods for your dynamic array
Atoms.Delete(500); // delete 500th item
A.ElementZ := 5000;
Atoms.Insert(500,A); // insert A values at 500th index
assert(Atoms.Count=10000);
assert(AtomCount=10000); // same as Atoms.Count
Atoms.Compare := SortDynArrayInteger;
Atoms.Sort; // will sort by 1st Integer value = ElementZ
for i := 1 to Atoms.Count-1 do // or AtomCount-1
// you have still direct access to AtomArray[]
// -> this is even the fastest access to the data
assert(AtomArray[i].ElementZ >=AtomArray[i-1].ElementZ )
Atoms.SaveToStream(aStream); // will also save any string content
Atoms.Reverse; // reverse all items order
Atoms.Clear;
// faster adding will be done with direct access to the dynamic array
Atom.Count := 10000; // allocate memory for 10000 items
for i := 0 to 10000-1 do
with AtomArray[i] do
begin
ElementZ := Random(2000);
X := Random;
Y := Random;
Z := Random;
end;
Atoms.Sort; // TDynArray knows about the data just created
end; // no need to have any try...finally ..Free block
Работает с Delphi 6 до XE.
С новой версией Delphi, поддерживающей дженерики, вам лучше пойти в этом направлении.