powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Статический массив неизвестной длины
25 сообщений из 32, страница 1 из 2
Статический массив неизвестной длины
    #39918378
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача: нужен класс контейнер, который будет хранить до 5-6 элементов. Количество элементов известно на этапе компиляции.

Писать так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
TContainer = class
  FChilds: array of TMyObject;
  constructor Create(ACount: Integer);
end;

constructor TContainer.Create(ACount: Integer);
begin
  SetLength(FChilds, ACount);
end;

не могу из-за жесткого ограничения по памяти (оверхед при выделении памяти для динамического массива, а контейнеров создается очень много). По этой же причине не нравится
Код: pascal
1.
GetMem(FChilds, ACount * SizeOf(TMyObject))



Сейчас делаю так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
TContainer1 = class
  FChild1: TMyObject;
end;

TContainer2 = class(TContainer1)
  FChild2: TMyObject;
end;
........
TContainer5 = class(TContainer4)
  FChild5: TMyObject;
end;

оверхеда нет вообще, но много кода.

Можно как-то подсократить?

Пытался так
Код: pascal
1.
2.
3.
TContainer<T> = class
  FChilds: array[0..SizeOf(T) - 1] of TMyObject;
end;

но компилятор не считает SizeOf(T) константой.

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918384
Sinemurius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сколько контейнеров и сколько элементов в одном контейнере Вы максимально хотите создать ?
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918398
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Задача: нужен класс контейнер, который будет хранить до 5-6 элементов. Количество элементов известно на этапе компиляции.

Писать так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
TContainer = class
  FChilds: array of TMyObject;
  constructor Create(ACount: Integer);
end;

constructor TContainer.Create(ACount: Integer);
begin
  SetLength(FChilds, ACount);
end;

не могу из-за жесткого ограничения по памяти (оверхед при выделении памяти для динамического массива, а контейнеров создается очень много). По этой же причине не нравится
Код: pascal
1.
GetMem(FChilds, ACount * SizeOf(TMyObject))



О каком оверхеде идет речь?
Код: pascal
1.
SetLength(FChilds, 1000);


выделит ~4 Кб памяти
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918400
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Перекрыть NewInstance не рассматривали? Можно выделить чуть больше памяти и хранить там массив, оверхеда быть не должно.
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918405
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
x1ca4064
Перекрыть NewInstance не рассматривали? Можно выделить чуть больше памяти и хранить там массив, оверхеда быть не должно.

А потом, кто-нибудь станет использовать для объекта синхронизацию монитором...
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918455
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кмк, говорить об оверхеде и при этом применять классы-контейнеры, содержащие классы же - это странно. Но окей, допустим.
В таком случае можно, например, использовать нечто вроде:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
TBaseContainer = class
  property Item read Get write Put
end;

TContainer1 = class(TBaseContainer)
  FObj1
end;

TContainer2 = class(TBaseContainer)
  FObj1, FObj2
end;

...

function CreateContainer(Num: Integer): TBaseContainer;
begin
  case Num of
    1: Result := TContainer1.Create;
   ...
end;

Container := CreateContainer(3);



UPD А еще (для любителей проктостоматологии) размер объекта у класса вычисляется как
Код: pascal
1.
2.
3.
4.
class function TObject.InstanceSize: Longint;
begin
  Result := PInteger(PByte(Self) + vmtInstanceSize)^;
end;


соответственно известно что делать
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918461
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Перейдете с классов на пакед рекорды - сэкономите память.
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918473
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще, если говорить о затратах памяти, любой объект изначально уже тратит больше 100 байт только на х32 (vmtCreateObject - vmtSelfPtr). Это еще не считая оверхеда менеджера памяти и своих виртуальных методов и не говоря про х64. Короче, классы - это не вариант, если нужно экономить память
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918477
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2
Вообще, если говорить о затратах памяти, любой объект изначально уже тратит больше 100 байт только на х32

Да ты гонишь. Объект минимум - 4 байта - ссылка на VMT класса.
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918491
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
Объект минимум - 4 байта

Сам себя поправлю, таки 8 байт. В размер включается ссылка на монитор. Соответственно, ничего страшного не случится даже если 22066064 .
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918493
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sinemurius
Сколько контейнеров
Много. Несколько сотен. Может тысяча
Sinemurius
и сколько элементов в одном контейнере Вы максимально хотите создать ?
Не более 4. Ну может где-то появится с 5
Квейд
О каком оверхеде идет речь?
Код: pascal
1.
SetLength(FChilds, 1000);


выделит ~4 Кб памяти
Код: pascal
1.
SetLength(FChilds, 2)

выделит 8 байт на сам массив + 8 байт на это
Код: pascal
1.
2.
3.
4.
5.
6.
7.
  TDynArrayRec = packed record
  {$IFDEF CPUX64}
    _Padding: LongInt; // Make 16 byte align for payload..
  {$ENDIF}
    RefCnt: LongInt;
    Length: NativeInt;
  end;

итого оверхед 50%
x1ca4064
Перекрыть NewInstance не рассматривали?
Так, мысль интересная. Нужно подумать.

Kazantsev Alexey
А потом, кто-нибудь станет использовать для объекта синхронизацию монитором...
И в чем противопоказания?

Василий 2
В таком случае можно, например, использовать нечто вроде
Вы исходный вопрос читали? Именно от этого варианта и хочется уйти
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918494
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
x1ca4064
Перекрыть NewInstance не рассматривали?
А как туда передать размер?
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918500
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
И в чем противопоказания?

Да уже ни в чём. InstanceSize возвращает размер с учётом ссылки на монитор.
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918501
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Много. Несколько сотен. Может тысяча

Эм... Это из-за 4-8 KB такая заморока???
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918511
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
Эм... Это из-за 4-8 KB такая заморока???
Нет. Почему-то отжирается памяти на порядок больше, чем общий размер объектов.

Создается тысячи мелких объектов (InstanceSize < 100 байт) и у системы отжирается 100 мегабайт. Создание этих объектов для 10 владельцев и OutOfMemory. Сейчас после базового рефракторинга удалось сократить базовое выделение до 20 мегабайт.

Где-то FastMM чудит и забирает у системы память сильно про запас
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918522
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Где-то FastMM чудит и забирает у системы память сильно про запас

Посмотри демку Usage Tracker. Она даёт полную картину выделения памяти, размеры блоков, степень оверхеда.
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918524
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2
Вообще, если говорить о затратах памяти, любой объект изначально уже тратит больше 100 байт только на х32 (vmtCreateObject - vmtSelfPtr). Это еще не считая оверхеда менеджера памяти и своих виртуальных методов и не говоря про х64. Короче, классы - это не вариант, если нужно экономить память


проверил. Что TObject.Create, что New(pInteger) занимают 16 байт (даже в x64). Видимо, для TObject там только указатель на VMT и резервный указатель на Monitor.
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918533
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот Usage Tracker. Можно посмотреть какие реальные размеры блоков использует менеджер. Например, при выделении 13 байт реально выделяется 20 из пула размером 29488. P.S. Данные для XE2, на более поздних они могут отличаться. P.P.S. Проверил в 10.3 - размеры те же.
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918540
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
10.3
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918549
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
Посмотри демку Usage Tracker.
Где ее брать?
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918551
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Где ее брать?

Стандартная демка дельфийская. Правда с какой-то версии её перестали поставлять, но в XE2 она точно есть. Может есть в их репе с демками.
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918553
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нашёл . XE6 последняя, где эта демка была.
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918585
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
x1ca4064
Перекрыть NewInstance не рассматривали?
А как туда передать размер?


Я бы делал через
Код: sql
1.
class function InternalArrayLength:integer; virtual;


соответственно для разных TContainer1..5 возвращал кол-во элементов массива, хотя можно и через какой-нибудь threadvar, но это как-то не так
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918587
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что мешает сделать статический массив максимального требуемого размера и использовать только нужную его часть?
Накладные расходы - пара лишних байт, тут уж точно никакого перерасхода памяти не будет.
...
Рейтинг: 0 / 0
Статический массив неизвестной длины
    #39918600
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

Зашибись, типа собственный менеджер памяти давай напишем.
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Статический массив неизвестной длины
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]