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