-
Здравствуйте. Код ниже прекрасно работает с SetLength(array, 1). Зачем выделять какую-то конкретную память больше 1? У меня только одна догадка, возможно реализация динамических массивов работает в разы быстрее, если память выделить зарание. Но если скорость не так важна, удобнее использовать минимальный размер массива, коотрый автоматом расширяется до некого неизвестного размера. var
a: array of integer;
begin
SetLength(a,1);
a[0] := 0;
a[1] := 1;
a[2] := 2;
a[3] := 3;
a[4] := 4;
WriteLn(a[0]);
WriteLn(a[1]);
WriteLn(a[2]);
WriteLn(a[3]);
WriteLn(a[4]);
end.
-
Попробуй a[1000000]:=1000000;
Потом поразмысли относительно памяти, в частности, как бы ты сам ее выделял и контролировал использование, если бы работал менеджером памяти.
-
Ну а в чём разница SetLength(a,1);
a[1000000]:=1000000; и SetLength(a,1000000);
a[1000000]:=1000000; ?
-
+ UPD, я понимаю, если надо убрать лишние элементы с конца динамического массива. Тогда имеет смысл сократить память на неиспрользуемую дельту. Опять же, если она именно с конца. Но я не понимаю механизма в динамическом массиве зарание выделять кол-во используемых элементов!?!
-
Чтобы расширить размер, надо выделить дополнительную память в конце массива, если она не зарезервирована заранее. Может оказаться, и чаще всего так будет, что память за массивом уже занята, тогда надо выделить в другом месте полный объём и скопировать в него все элементы массива, старый участок освободить. Представь себе, что будет, если это проделывать для каждого нового элемента. Во-первых, скорость, во-вторых фрагментация.
-
>динамическом массиве Вот именно. Его можно расширить, сжать и обнулить. Не динамический массив придется обнулить и создать заново.
-
списки круче.
> Вячеслав (26.02.17 23:54) [2] > Ну а в чём разница > > SetLength(a,1); > a[1000000]:=1000000; > и > SetLength(a,1000000); > a[1000000]:=1000000; > > ?
в данном примере первая часть эвивалентна второй в такой записи: SetLength(a,1); SetLength(a,1000000); a[1000000]:=1000000; если не учитывать ошибку; но если ошибку учитывать, то они равнозначны
-
Понял. Подскажите, есть ли в языке готовая такая "сущность", которая имитирует некий резиновый динамический массив или хеш, который расширяется автоматом при добавлении в него элемента? По сути для меня есть только 2 требования (синтаксис не важен): 1) a[] = 1 или a[Size(a)-1] = 1 автоматом добавляет элемент в конец массива и увеличивает его Size\Length на еденицу. 2) Есть метод или функция удаления элемента, что мнговенно влияет на Size или Length. Т.е. я всегда могу знать, сколько значимых элементов в этом динамическом массиве измеряв его.
-
TList идеально подходит, если требования только эти.
-
> 1) a[] = 1 или a[Size(a)-1] = 1 автоматом добавляет элемент > в конец массива и увеличивает его Size\Length на еденицу. >
Увеличение при каждом "чихе" на едИницу не очень есть оптимально. Ибо приводит к излишне частому перераспределению памяти, а в ряде случаев может привести и к слишком сильной фрагментации памяти. Из-за чего приложение более не сможет работать. Поэтому TList при необходимости увеличения размера списка увеличивает его не на едИницу, а на несколько большую величину. Так что присоединяюсь к сторонникам использования списков vs динамических массивов. P.S. Хотя, конечно, список - тот же самый динамический массив. Но уже готовый к употреблению. :)
-
> Германн © (28.02.17 01:56) [9]
Использование списков или дин.массивов всё-таки зависит от: а) конкретной задачи; б) наличия того или иного (в с# с динамическими массивами несколько туговато).
-
Вячеслав (27.02.17 12:27) [7] Лучше свой класс написать. У меня так например сделано:
const MinBlockSize = 100;
procedure TPObject.AddPoint(P: TPoint); begin //Добавляем память блоками if (FNumPoints mod MinBlockSize) = 0 then begin SetLength(FPoints, FNumPoints + MinBlockSize); end; Inc(FNumPoints); FPoints[FNumPoints - 1] := P; end;
Чтобы ускорить добавляю память блоками. По одному элементу может стать затратно по производительности. Менеджер памяти каждый раз создает новый блок и переписывает данные в него. На массиве в 10000 элементов уже "тормоза" заметны в вашем случае с одним элементом.
|