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 тоже можно применить.