Каждый раз, когда вы вызываете SetLength
память, происходит перераспределение. Возможно, весь массив нужно скопировать в другое место. И вы, которые просто хотели добавить один элемент в массив!
В принципе: никогда не делайте этого. Есть два выхода из этого. Самый простой случай - если вы заранее знаете максимальный размер массива:
procedure Example1;
var
data: array of string;
ActualLength: integer;
procedure AddElement(const Str: string);
begin
data[ActualLength] := Str;
inc(ActualLength);
end;
begin
ActualLength := 0;
SetLength(data, KNOWN_UPPER_BOUND);
for ...
while ...
repeat ...
AddElement(SomeString);
SetLength(data, ActualLength);
end;
Вот пример практического примера этого подхода.
Если вы не знаете какую-либо верхнюю границу априори , а затем выделите большие куски:
procedure Example2;
const
ALLOC_BY = 1024;
var
data: array of string;
ActualLength: integer;
procedure AddElement(const Str: string);
begin
if ActualLength = length(data) then
SetLength(data, length(data) + ALLOC_BY);
data[ActualLength] := Str;
inc(ActualLength);
end;
begin
ActualLength := 0;
SetLength(data, ALLOC_BY);
for ...
while ...
repeat ...
AddElement(SomeString);
SetLength(data, ActualLength);
end;
Этот второй подход реализован в время выполнения библиотеки TList<T>
, TObjectList<T>
, и TStringList
т.д. Таким образом, когда вы используете эти классы, это прекрасно , чтобы добавить в список по одному элементу за раз.