- Код: Выделить всё
-   function GetName(Value: integer): string;
 begin
 Value:=Value xor $55555555;
 Result := format('MapElementKey %10d', [Value]);
 end;
такой перемес тебя устроит?
без разницы в каком порядке искать, время на создание тебе так важно? - тоже сомневаюсь что оно сильно изменится
Добавлено спустя 6 часов 38 минут 28 секунд:такие циферки:
- Код: Выделить всё
- E:zcadothermaptestsdelphiDebugWin32>E:zcadothermaptestsdelphiDebugWin32genericscollections.exe
 Summ of       10 elenents          55, time 0,0000115739sec
 Summ of      100 elenents        5050, time 0,0000543980sec
 Summ of     1000 elenents      500500, time 0,0003888890sec
 Summ of    10000 elenents    50005000, time 0,0039352017sec
 Summ of   100000 elenents   705082704, time 0,0428241037sec
 Summ of  1000000 elenents  1784293664, time 0,4664347216sec
 Summ of 10000000 elenents -2004260032, time 4,8391208111sec
 Destroy 2,1296sec
 
 E:zcadothermaptests>E:zcadothermaptestsgenericscollections.exe
 Summ of       10 elenents          55, time 0,0000208332sec
 Summ of      100 elenents        5050, time 0,0000925924sec
 Summ of     1000 elenents      500500, time 0,0007789349sec
 Summ of    10000 elenents    50005000, time 0,0079860911sec
 Summ of   100000 elenents   705082704, time 0,0832176011sec
 Summ of  1000000 elenents  1784293664, time 0,8865739801sec
 Summ of 10000000 elenents -2004260032, time 9,6678246337sec
 Destroy 2,2025sec
 
 E:zcadothermaptests>E:zcadothermaptestshashmaptest.exe
 Summ of       10 elenents          55, time 0,0000266205sec
 Summ of      100 elenents        5050, time 0,0000925931sec
 Summ of     1000 elenents      500500, time 0,0008125004sec
 Summ of    10000 elenents    50005000, time 0,0081018516sec
 Summ of   100000 elenents   705082704, time 0,0959490717sec
 Summ of  1000000 elenents  1784293664, time 1,0682873835sec
 Summ of 10000000 elenents -2004260032, time 11,2060180982sec
 Destroy 4,0417sec
 
 E:zcadothermaptests>E:zcadothermaptestsdmaptest.exe
 Summ of       10 elenents          55, time 0,0000219909sec
 Summ of      100 elenents        5050, time 0,0001238426sec
 Summ of     1000 elenents      500500, time 0,0013807869sec
 Summ of    10000 elenents    50005000, time 0,0165509118sec
 Summ of   100000 elenents   705082704, time 0,1899305789sec
 Summ of  1000000 elenents  1784293664, time 2,1701394871sec
 Summ of 10000000 elenents -2004260032, time 24,3136571953sec
 Destroy 0,9236sec
 
 E:zcadothermaptests>E:zcadothermaptestsmaptest.exe
 Summ of       10 elenents          55, time 0,0000254629sec
 Summ of      100 elenents        5050, time 0,0001527776sec
 Summ of     1000 elenents      500500, time 0,0019004634sec
 Summ of    10000 elenents    50005000, time 0,0239583460sec
 Summ of   100000 elenents   705082704, time 0,2863426198sec
 Summ of  1000000 elenents  1784293664, time 3,3414347854sec
 Summ of 10000000 elenents -2004260032, time 38,0231482268sec
 Destroy 1,3414sec
1-delphi xe generics.collections
2-generics.collections 
3-THashMap в качестве хэша - DelphiHashLittle
4-DMap
5-TMap
- Код: Выделить всё
- program genericscollections;
 {$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
 {$APPTYPE CONSOLE}
 uses
 generics.collections,
 sysutils;
 
 const
 elemcount=10000000;
 type
 TKeyType=string;
 TMyMapElement = record
 Value:integer;
 end;
 TMyMap = TDictionary<TKeyType, TMyMapElement>;
 
 
 function GetName(value:integer):string;
 begin
 if (value and 1)>0 then
 value:=elemcount-value;
 value:=value xor $55555555;
 result:=format('MapElementKey %10d',[value]);
 end;
 
 function NeedTestsCount(value:integer):integer;
 begin
 case value of
 10,100,1000:result:=1000;
 10000,100000:result:=10;
 1000000,10000000:result:=1;
 else result:=0;
 end;
 end;
 
 function TMapElement_Create(_value:integer):TMyMapElement;
 begin
 result.Value:=_value;
 end;
 var
 m:TMyMap;
 i,j,k:integer;
 sum,testcount:integer;
 myTime:TDateTime;
 begin
 m:=TMyMap.Create;
 
 for i:=1 to elemcount do
 begin
 m.add(GetName(i),TMapElement_Create(i));
 testcount:=NeedTestsCount(i);
 if testcount>0 then
 begin
 myTime:=now;
 for j:=1 to testcount do
 begin
 sum:=0;
 for k:=1 to i do
 sum:=sum+m.Items[GetName(k)].Value;
 end;
 writeln(format('Summ of %8d elenents %11d, time %.10fsec',[i,sum,((now-myTime)/testcount)*10e4]));
 end;
 end;
 
 myTime:=now;
 m.Destroy;
 writeln(format('Destroy %.4fsec',[(now-myTime)*10e4]));
 end.
- Код: Выделить всё
- program genericscollections;
 {$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
 {$APPTYPE CONSOLE}
 uses
 {$IFDEF UNIX}{$IFDEF UseCThreads}
 cthreads,
 {$ENDIF}{$ENDIF}
 generics.collections,
 sysutils;
 
 const
 elemcount=10000000;
 type
 TKeyType=string;
 TMyMapElement = record
 Value:integer;
 end;
 TMyMap = TDictionary<TKeyType, TMyMapElement>;
 
 
 function GetName(value:integer):string;
 begin
 if (value and 1)>0 then
 value:=elemcount-value;
 value:=value xor $55555555;
 result:=format('MapElementKey %10d',[value]);
 end;
 
 function NeedTestsCount(value:integer):integer;
 begin
 case value of
 10,100,1000:result:=1000;
 10000,100000:result:=10;
 1000000,10000000:result:=1;
 else result:=0;
 end;
 end;
 
 function TMapElement_Create(_value:integer):TMyMapElement;
 begin
 result.Value:=_value;
 end;
 var
 m:TMyMap;
 i,j,k:integer;
 sum,testcount:integer;
 myTime:TDateTime;
 begin
 m:=TMyMap.Create;
 
 for i:=1 to elemcount do
 begin
 m.add(GetName(i),TMapElement_Create(i));
 testcount:=NeedTestsCount(i);
 if testcount>0 then
 begin
 myTime:=now;
 for j:=1 to testcount do
 begin
 sum:=0;
 for k:=1 to i do
 sum:=sum+m.Items[GetName(k)].Value;
 end;
 writeln(format('Summ of %8d elenents %11d, time %.10fsec',[i,sum,((now-myTime)/testcount)*10e4]));
 end;
 end;
 
 myTime:=now;
 m.Destroy;
 writeln(format('Destroy %.4fsec',[(now-myTime)*10e4]));
 end.
- Код: Выделить всё
- program hashmaptest;
 uses
 ghashmap,gutil,sysutils,Generics.Hashes;
 const
 elemcount=10000000;
 type
 TKeyType=string;
 TMyMapElement=record
 Value:integer;
 end;
 MyStringHash=class
 class function hash(s:TKeyType; n:longint):SizeUInt;
 end;
 TMyMap = specialize THashMap<TKeyType, TMyMapElement, MyStringHash>;
 
 function MakeHash(const s:TKeyType):SizeUInt;
 begin
 result:=DelphiHashLittle(@s[1],length(s)*sizeof(s[1]),0);
 end;
 
 class function MyStringHash.hash(s:TKeyType; n:longint):SizeUInt;
 begin
 result:=makehash(s) mod SizeUInt(n);
 end;
 
 function GetName(value:integer):string;
 begin
 if (value and 1)>0 then
 value:=elemcount-value;
 value:=value xor $55555555;
 result:=format('MapElementKey %10d',[value]);
 end;
 
 function NeedTestsCount(value:integer):integer;
 begin
 case value of
 10,100,1000:result:=1000;
 10000,100000:result:=10;
 1000000,10000000:result:=1;
 else result:=0;
 end;
 end;
 
 function TMapElement_Create(_value:integer):TMyMapElement;
 begin
 result.Value:=_value;
 end;
 
 var
 m:TMyMap;
 i,j,k:integer;
 sum,testcount:integer;
 myTime:TDateTime;
 begin
 m:=TMyMap.Create;
 
 for i:=1 to elemcount do
 begin
 m.Insert(GetName(i),TMapElement_Create(i));
 testcount:=NeedTestsCount(i);
 if testcount>0 then
 begin
 myTime:=now;
 for j:=1 to testcount do
 begin
 sum:=0;
 for k:=1 to i do
 sum:=sum+m.Items[GetName(k)].Value;
 end;
 writeln(format('Summ of %8d elenents %11d, time %.10fsec',[i,sum,((now-myTime)/testcount)*10e4]));
 end;
 end;
 
 myTime:=now;
 m.Destroy;
 writeln(format('Destroy %.4fsec',[(now-myTime)*10e4]));
 end.
- Код: Выделить всё
- program hashmaptest;
 {$APPTYPE CONSOLE}
 
 uses
 decal,
 SysUtils;
 
 const
 elemcount = 10000000;
 
 type
 TKeyType=string;
 TMyMapElement = class
 Value: integer;
 end;
 function TMapElement_Create(_value: integer): TMyMapElement;
 var
 me: TMyMapElement;
 begin
 me := TMyMapElement.Create;
 me.Value := _value;
 exit(me);
 end;
 function GetName(value:integer):TKeyType;
 begin
 if (value and 1)>0 then
 value:=elemcount-value;
 value:=value xor $55555555;
 result:=format('MapElementKey %10d',[value]);
 end;
 
 function NeedTestsCount(value:integer):integer;
 begin
 case value of
 10,100,1000:result:=1000;
 10000,100000:result:=10;
 1000000,10000000:result:=1;
 else result:=0;
 end;
 end;
 
 var
 m: DMap;
 i,j,k,testcount: integer;
 sum: integer;
 myTime: TDateTime;
 begin
 m:=DMap.Create;
 
 for i:=1 to elemcount do
 begin
 m.PutPair([GetName(i), TMapElement_Create(i)]);
 testcount:=NeedTestsCount(i);
 if testcount>0 then
 begin
 myTime:=now;
 for j:=1 to testcount do
 begin
 sum:=0;
 for k:=1 to i do
 Sum := Sum + TMyMapElement(getObject(m.locate([GetName(k)]))).Value;
 end;
 writeln(format('Summ of %8d elenents %11d, time %.10fsec',[i,sum,((now-myTime)/testcount)*10e4]));
 end;
 end;
 
 myTime:=now;
 m.Destroy;
 writeln(format('Destroy %.4fsec',[(now-myTime)*10e4]));
 end.
- Код: Выделить всё
- 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
 if (value and 1)>0 then
 value:=elemcount-value;
 value:=value xor $55555555;
 result:=format('MapElementKey %10d',[value]);
 end;
 
 function NeedTestsCount(value:integer):integer;
 begin
 case value of
 10,100,1000:result:=1000;
 10000,100000:result:=10;
 1000000,10000000:result:=1;
 else result:=0;
 end;
 end;
 
 function TMapElement_Create(_value:integer):TMyMapElement;
 begin
 result.Value:=_value;
 end;
 var
 m:TMyMap;
 i,j,k:integer;
 sum,testcount:integer;
 myTime:TDateTime;
 begin
 m:=TMyMap.Create;
 
 for i:=1 to elemcount do
 begin
 m.Insert(GetName(i),TMapElement_Create(i));
 testcount:=NeedTestsCount(i);
 if testcount>0 then
 begin
 myTime:=now;
 for j:=1 to testcount do
 begin
 sum:=0;
 for k:=1 to i do
 sum:=sum+m.Items[GetName(k)].Value;
 end;
 writeln(format('Summ of %8d elenents %11d, time %.10fsec',[i,sum,((now-myTime)/testcount)*10e4]));
 end;
 end;
 
 myTime:=now;
 m.Destroy;
 writeln(format('Destroy %.4fsec',[(now-myTime)*10e4]));
 end.
Любопытно что скомпиленое fpc моментально раскручивает вентилятор проца на максимум, скомпиленое делфи оставляет его на минимальных оборотах
Добавлено спустя 2 часа 26 минут 8 секунд:ключ заменен на integer
- Код: Выделить всё
- E:zcadothermaptestsdelphiDebugWin32>E:zcadothermaptestsdelphiDebugWin32genericscollections.exe
 Summ of       10 elenents          55, time 0,0000023145sec
 Summ of      100 elenents        5050, time 0,0000208332sec
 Summ of     1000 elenents      500500, time 0,0000787040sec
 Summ of    10000 elenents    50005000, time 0,0008101779sec
 Summ of   100000 elenents   705082704, time 0,0090277899sec
 Summ of  1000000 elenents  1784293664, time 0,1423613867sec
 Summ of 10000000 elenents -2004260032, time 1,6504629457sec
 Destroy 0,1701sec
 
 E:zcadothermaptests>E:zcadothermaptestsgenericscollections.exe
 Summ of       10 elenents          55, time 0,0000011576sec
 Summ of      100 elenents        5050, time 0,0000138883sec
 Summ of     1000 elenents      500500, time 0,0000648150sec
 Summ of    10000 elenents    50005000, time 0,0004628964sec
 Summ of   100000 elenents   705082704, time 0,0061342143sec
 Summ of  1000000 elenents  1784293664, time 0,1168984454sec
 Summ of 10000000 elenents -2004260032, time 1,4212964743sec
 Destroy 0,1655sec
 
 E:zcadothermaptests>E:zcadothermaptestsmaptest.exe
 Summ of       10 elenents          55, time 0,0000000000sec
 Summ of      100 elenents        5050, time 0,0000069442sec
 Summ of     1000 elenents      500500, time 0,0000706023sec
 Summ of    10000 elenents    50005000, time 0,0006944174sec
 Summ of   100000 elenents   705082704, time 0,0075231947sec
 Summ of  1000000 elenents  1784293664, time 0,0949075911sec
 Summ of 10000000 elenents -2004260032, time 1,1574076780sec
 Destroy 0,5648sec
 
 E:zcadothermaptests>E:zcadothermaptestshashmaptest.exe
 Summ of       10 elenents          55, time 0,0000011569sec
 Summ of      100 elenents        5050, time 0,0000115739sec
 Summ of     1000 elenents      500500, time 0,0000648150sec
 Summ of    10000 elenents    50005000, time 0,0008101779sec
 Summ of   100000 elenents   705082704, time 0,0144675869sec
 Summ of  1000000 elenents  1784293664, time 0,2708336979sec
 Summ of 10000000 elenents -2004260032, time 3,4444441553sec
 Destroy 1,7731sec
 
 E:zcadothermaptests>E:zcadothermaptestsdmaptest.exe
 Summ of       10 elenents          55, time 0,0000069442sec
 Summ of      100 elenents        5050, time 0,0000497690sec
 Summ of     1000 elenents      500500, time 0,0005740745sec
 Summ of    10000 elenents    50005000, time 0,0074074342sec
 Summ of   100000 elenents   705082704, time 0,0878472201sec
 Summ of  1000000 elenents  1784293664, time 1,0543983080sec
 Summ of 10000000 elenents -2004260032, time 11,9351847388sec
 Destroy 0,4086sec
TMap выходит в лидеры
Добавлено спустя 23 минуты 38 секунд:Если в качестве хэша возвращать сам ключь
- Код: Выделить всё
- E:\zcad\other\maptests>E:\zcad\other\maptests\hashmaptest.exe
 Summ of       10 elenents          55, time 0,0000000000sec
 Summ of      100 elenents        5050, time 0,0000046297sec
 Summ of     1000 elenents      500500, time 0,0000428241sec
 Summ of    10000 elenents    50005000, time 0,0004628964sec
 Summ of   100000 elenents   705082704, time 0,0024305336sec
 Summ of  1000000 elenents  1784293664, time 0,0266205461sec
 Summ of 10000000 elenents -2004260032, time 0,3043984179sec
 Destroy 1,0637sec
В TMap всетаки какието проблемы, THashMap рулит