Уничтожение значений-объектов массива TMap из FCL-STL

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение zub » 01.04.2017 15:44:48

Лекс Айрин писал(а):Я о них помню. Это дублирование object/class мне столько крови попортило. В конце-концов, чисто для себя, признал object записью на "стероидах". Имхо, их наличие только портит "картину мира".

объекты - полноценный ооп контейнер. Класс - какоето недоразумение))
zub
долгожитель
 
Сообщения: 2048
Зарегистрирован: 14.11.2005 23:51:26

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение Лекс Айрин » 01.04.2017 15:47:15

zub, это, на самом деле, уже не принципиально. Все равно, в ближайшие года три-четыре никто не будет переделывать спецификацию языка.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 3715
Зарегистрирован: 19.02.2013 16:54:51

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение Снег Север » 01.04.2017 16:39:39

zub писал(а):объекты - полноценный ооп контейнер. Класс - какоето недоразумение))
Объекты турбопаскаля и классы - это как паровая машина Уатта и современная паровая турбина... :)
Аватара пользователя
Снег Север
энтузиаст
 
Сообщения: 909
Зарегистрирован: 27.11.2007 16:14:47

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение java73 » 01.04.2017 19:02:16

vitaly_l писал(а):ТС же уже рассказал, что ему нужно всего лишь получить значения нескольких input из HTML. Уже второй месяц, весь форум ищет решение этой наисложнейшей задачи

Хоть как-то вас развлекать пытаюсь. Парсер то уже готов неделю как, в двух вариантах, так что я просто полирую и продолжаю изучать тонкости языка.
java73
постоялец
 
Сообщения: 191
Зарегистрирован: 21.11.2013 09:08:10

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение serbod » 02.04.2017 00:14:06

zub писал(а):Вот мне нужен массив 10e6 элементов содержащих некие координаты - x,y:byte - следуя вашим советам я получу огромный оверхед как по расходу памяти, так и по скорости исполнения.

В данной теме речь идет не о массиве байтов, а о словаре элементов (состоящих из строк), которые нужно удалять из памяти после использования. Конкретно для этого случая array неудобен.

Напомню, что проблема была не в производительности, а в утечке памяти. Подчиненные объекты эту проблему решают. Array or record тоже решает, но менее комфортно и в дальнейшем придется переделывать.
Аватара пользователя
serbod
постоялец
 
Сообщения: 108
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение zub » 02.04.2017 08:38:32

serbod
>>Подчиненные объекты эту проблему решают.
Проблему решает пробежка по "массиву" и вызов деструктора. Вы советуете какието чудесные "Подчиненные объекты" - вроде как решающие проблему, но забываете расказать про реализацию этих подчиненных объектов - у объекта "владельца" есть список подчиненных "объектов" - при своем уничтожении он проходит по этому списку и уничтожает "подчиненных". Зачем нам 2 массива вместо одного? да еще и доступ по ссылке вместо прямого?

>>В данной теме речь идет не о массиве байтов, а о словаре элементов (состоящих из строк), которые нужно удалять из памяти после использования. Конкретно для этого случая array неудобен.
Я не про строики и не про массивы. Я про размер элемента - хранить мелочь (структура из 3х стрингов это 3*sizeof(pointer) байт - мелочь) с доступом по ссылке (класс всегда в куче) - расточительство. Для крупных структур, или там где будет полиморфизм - пожалуйста. Для мелочи - рекорд или обжект гораздо лучше.

Снег Север писал(а):Объекты турбопаскаля и классы - это как паровая машина Уатта и современная паровая турбина...

Фундаментальное отличие только одно, и оно не в пользу класса
zub
долгожитель
 
Сообщения: 2048
Зарегистрирован: 14.11.2005 23:51:26

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение Azazaz » 02.04.2017 14:05:56

Уличная магия:
Код: Выделить всё
type
TKey = (One, Two, Three);
TEl = array[TKey]of String;
var
A: TEl;
begin
A[One]:= '123';
A[Two]:= 'Stepan';
Writeln(A[One], LineEnding, A[Two]);
readln;
end.
Azazaz
новенький
 
Сообщения: 38
Зарегистрирован: 21.04.2015 20:00:03

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение java73 » 02.04.2017 14:18:11

У нас тут более сильное колдунство: создавать ключи и массив динамически, не зная заранее ни их имен, ни количества.
java73
постоялец
 
Сообщения: 191
Зарегистрирован: 21.11.2013 09:08:10

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение vitaly_l » 02.04.2017 15:08:45

java73 писал(а):У нас тут более сильное колдунство: создавать ключи и массив динамически, не зная заранее ни их имен, ни количества.


Ну вообще-то, в коде следует заменить вот это KeyType: string; на вот это:
Код: Выделить всё
type
TKeyType = (ktCheckBox, ktText);

TMapElement = record
    KeyType: TKeyType;
    Value: string;
  end;

Так будет более грамотно. Соответственно Вам дали хороший совет, а Вы опять всё прошляпили.

Насколько я помню, Вы - один из тех великих программистов, которые всегда пишут код без ошибок. Верно?
.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 2824
Зарегистрирован: 31.01.2012 16:41:41

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение java73 » 02.04.2017 15:56:55

Где я что прошляпил, у вас там все смешалось опять?
Мне посоветовали fcl использовать тип TMap (нет, советовали хэшмап, но я все ж подумал, что из пушки по воробьям бить не стоит), а не deCAL - Хорошо, я использую fcl тип TMap.
Мне посоветовали вместо классов использовать записи - хорошо, я написал, что использую записи.
Где я что прошляпил? И о каких ошибках в данном случае речь?
Вся дальнейшая переписка вышла далеко за рамки моего вопроса.
Не обязательно на личности переходить, но без этого не можете, то не обращайте, пожалуйста, вашего внимания на мои сообщения и вопросы. А что касается того случая, где мы вдвоем написали, что ошибка не у нас, так время все расставило на свои места - ошибка, действительно, была не у нас, а в lcl.
И еще раз напомню, я не программист, не учился, дипломы не получал, на хакатонах не выступал, тем не менее всегда нахожу время на своей работе, чтобы изучить что-то полезное - книжки про паттерны прочитать, изучить дженерики наконец-то. А почему нахожу время? Да потому что сделал кучу программ, которые работают за меня)) вот и всё.
java73
постоялец
 
Сообщения: 191
Зарегистрирован: 21.11.2013 09:08:10

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение zub » 02.04.2017 17:53:23

На художников нет никакой надежды. как обычно.
Код: Выделить всё
program maptest;
uses
  gmap,gutil,sysutils;
const
  elemcount=10000000;
type
TMyMapElement = record
  Value:integer;
end;
Less=specialize TLess<string>;
TMyMap = specialize TMap<string, TMyMapElement, Less>;


function GetName(value:integer):string;
begin
  result:=format('MapElementKey %10d',[value]);
end;

function TMapElement_Create(_value:integer):TMyMapElement;
begin
  result.Value:=_value;
end;
var
  m:TMyMap;
  s,ts:string;
  i:integer;
  sum:integer;
  myTime:TDateTime;
  mapelement:TMyMapElement;
begin
  m:=TMyMap.Create;

  myTime:=now;
  for i:=1 to elemcount do
  m.Insert(GetName(i),TMapElement_Create(i));
  str((now-myTime)*10e4:2:3,ts);
  writeln('Insert    '+ts+'sec.');

  sum:=0;
  myTime:=now;
  for i:=1 to elemcount do
  sum:=sum+m.Items[GetName(i)].Value;
  str((now-myTime)*10e4:2:3,ts);
  writeln('Calculate '+ts+'sec.');
  writeln('Sum=',sum);

  myTime:=now;
  m.Destroy;
  str((now-myTime)*10e4:2:3,ts);
  writeln('Destroy   '+ts+'sec.');
  readln;
end.

Код: Выделить всё
program hashmaptest;
uses
  ghashmap,gutil,sysutils;
const
  elemcount=10000000;
type
TMyMapElement = record
  Value:integer;
end;
MyStringHash=class
  class function hash(s:AnsiString; n:longint):SizeUInt;
end;
TMyMap = specialize THashMap<string, TMyMapElement, MyStringHash>;

function MakeHash(const s:AnsiString):SizeUInt;
var
  I: Integer;
begin
  Result := 0;
  for I := 1 to Length(s) do
    Result := ((Result shl 7) or (Result shr 25)) + Ord(s[I]);
end;

class function MyStringHash.hash(s:String; n:longint):SizeUInt;
begin
     result:=makehash(s) mod SizeUInt(n);
end;

function GetName(value:integer):string;
begin
  result:=format('MapElementKey %10d',[value]);
end;

function TMapElement_Create(_value:integer):TMyMapElement;
begin
  result.Value:=_value;
end;
var
  m:TMyMap;
  s,ts:string;
  i:integer;
  sum:integer;
  myTime:TDateTime;
  mapelement:TMyMapElement;
begin
  m:=TMyMap.Create;

  myTime:=now;
  for i:=1 to elemcount do
  m.Insert(GetName(i),TMapElement_Create(i));
  str((now-myTime)*10e4:2:3,ts);
  writeln('Insert    '+ts+'sec.');

  sum:=0;
  myTime:=now;
  for i:=1 to elemcount do
  sum:=sum+m.Items[GetName(i)].Value;
  str((now-myTime)*10e4:2:3,ts);
  writeln('Calculate '+ts+'sec.');
  writeln('Sum=',sum);

  myTime:=now;
  m.Destroy;
  str((now-myTime)*10e4:2:3,ts);
  writeln('Destroy   '+ts+'sec.');
  readln;
end.

у меня получмилось:
E:\zcad\other\maptests>E:\zcad\other\maptests\maptest.exe
Insert 78.245sec.
Calculate 51.152sec.
Sum=-2004260032
Destroy 0.932sec.


E:\zcad\other\maptests>E:\zcad\other\maptests\hashmaptest.exe
Insert 50.442sec.
Calculate 22.711sec.
Sum=-2004260032
Destroy 1.912sec.

java73
Сделайте аналогичный тест для decal - обмерим пиписьки. Только именно аналогичный - с такимиже именами ключей
zub
долгожитель
 
Сообщения: 2048
Зарегистрирован: 14.11.2005 23:51:26

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение java73 » 02.04.2017 19:14:44

zub писал(а):java73
Сделайте аналогичный тест для decal - обмерим пиписьки. Только именно аналогичный - с такимиже именами ключей

Ну сами хотели)))
Прелюдия: уж не знаю, что там у вас за компьютер, но с десятью миллионами у меня хэшмапы вставали намертво. Я лишь наблюдал, как рос расход памяти пять минут и на гигабайте убивал процесс. Снизил в тестах до одного миллиона, вот результаты:
1. TMap
Код: Выделить всё
alex@alex-GA-MA785GT-UD3H:~/Документы/lazarus-projects/maptest/maptest1$ ./maptest
Insert    13.688sec.
Calculate 9.850sec.
Sum=1784293664
Destroy   0.890sec.


2. THashMap
Код: Выделить всё
alex@alex-GA-MA785GT-UD3H:~/Документы/lazarus-projects/maptest/maptest2$ ./project1
Insert    128.816sec.
Calculate 69.175sec.
Sum=1784293664
Destroy   0.608sec.


3. DMap
Код: Выделить всё
alex@alex-GA-MA785GT-UD3H:~/Документы/lazarus-projects/maptest/maptest3$ ./project1
Insert    10.208sec.
Calculate 0.115sec.
Sum=1784293664
Destroy   1.007sec.


Код проекта на декале:
Код: Выделить всё
program hashmaptest;

uses
  decal,
  SysUtils;

const
  elemcount = 1000000;
type
  TMyMapElement = class
    Value: integer;
  end;

   function GetName(Value: integer): string;
  begin
    Result := format('MapElementKey %10d', [Value]);
  end;

  function TMapElement_Create(_value: integer): TMyMapElement;
  var me: TMyMapElement;
  begin
    me:=TMyMapElement.Create;
    me.Value := _value;
    exit(me);
  end;

var
  m: DMap;
  s, ts: string;
  i: integer;
  iter: DIterator;
  sum: integer;
  myTime: TDateTime;
  mapelement: TMyMapElement;
begin
  m := DMap.Create;

  myTime := now;
  for i := 1 to elemcount do
    m.PutPair([GetName(i), TMapElement_Create(i)]);
  str((now - myTime) * 10e4: 2: 3, ts);
  writeln('Insert    ' + ts + 'sec.');

  sum := 0;
  myTime := now;
  Iter:=m.Start;
  While iterateOver(Iter) do
    Sum:=Sum+TMyMapElement(getObject(Iter)).Value;
  str((now - myTime) * 10e4: 2: 3, ts);
  writeln('Calculate ' + ts + 'sec.');
  writeln('Sum=', sum);

  myTime := now;
  ObjFree(m);
  m.Free;
  str((now - myTime) * 10e4: 2: 3, ts);
  writeln('Destroy   ' + ts + 'sec.');
  readln;
end.


Да, декаловский массив не может взять запись как элемент массива, только объект или атомарный тип данных. Поэтому запись превратил в класс. Если хотите, для чистоты эксперимента, сейчас и для первых двух сделаю в классах.

Добавлено спустя 10 минут 51 секунду:
Вот в догонку чистый заезд (на классах, 10 млн вернул взад) между Dmap и TMap
Код: Выделить всё
alex@alex-GA-MA785GT-UD3H:~/Документы/lazarus-projects/maptest/maptest3$ ./project1
Insert    46.480sec.
Calculate 0.957sec.
Sum=-2004260032
Destroy   2.568sec.

alex@alex-GA-MA785GT-UD3H:~/Документы/lazarus-projects/maptest/maptest3$ cd ../maptest1
alex@alex-GA-MA785GT-UD3H:~/Документы/lazarus-projects/maptest/maptest1$ ./maptest
Insert    103.227sec.
Calculate 61.343sec.
Sum=-2004260032
Destroy   1.566sec.



Догадаетесь, где кто?

Добавлено спустя 10 минут 44 секунды:
И совсем уж чистейший эксперимент. Поскольку вы малость извратили вторым for'ом, подсчитывающим сумму, всю суть ассоциированных массивов, я тоже изменил второй цикл в декаловском примере:
Код: Выделить всё
for i:=1 to elemcount do
    Sum:=Sum+TMyMapElement(getObject(m.locate([GetName(i)]))).Value; \0


Утешительного здесь мало, поскольку и в таком случае декал В ДВА раза быстрее:
Код: Выделить всё
alex@alex-GA-MA785GT-UD3H:~/Документы/lazarus-projects/maptest/maptest3$ ./project1
Insert    53.112sec.
Calculate 32.549sec.
Sum=-2004260032
Destroy   2.536sec.


Вы же специально сделали циклом перебор не ПОСЛЕДОВАТЕЛЬНО, а в разнобой? Для последовательного перебора я применил итератор, его и в случае с TMap тоже можно применить.
java73
постоялец
 
Сообщения: 191
Зарегистрирован: 21.11.2013 09:08:10

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение vitaly_l » 02.04.2017 19:36:30

java73 писал(а):Догадаетесь, где кто?

А чего тут догадываться, вот нормальный результат.
Код: Выделить всё
Insert    0.006sec.
Calculate 0.006sec.
Sum=1784293664
Destroy   0.000sec.                         
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 2824
Зарегистрирован: 31.01.2012 16:41:41

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение java73 » 02.04.2017 19:47:02

Меняю своё железо на ваше)
java73
постоялец
 
Сообщения: 191
Зарегистрирован: 21.11.2013 09:08:10

Re: Уничтожение значений-объектов массива TMap из FCL-STL

Сообщение vitaly_l » 02.04.2017 19:51:41

java73 писал(а):Меняю своё железо на ваше)

:roll: Мой комп, в полтора раза медленнее, чем машина Zub-а :cry: .
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 2824
Зарегистрирован: 31.01.2012 16:41:41

Пред.След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru
cron