55// a dedicated hash table is 40% faster than mORMot generic TDynArrayHashed
66
77{ $define CUSTOMASM}
8- // a few % faster with some dedicated asm instead of mORMot code on x86_64
8+ // about 10 % faster with some dedicated asm instead of mORMot code on x86_64
99
1010{ $I mormot.defines.inc}
1111
@@ -101,14 +101,14 @@ procedure TBrcList.Init(max: integer; align: boolean);
101101 SetLength(StationMem, max); // RTL won't align by 64 bytes
102102 Station := pointer(StationMem);
103103 if align then
104- while PtrUInt(Station) and 63 <> 0 do // manual alignment
104+ while { %H- } PtrUInt(Station) and 63 <> 0 do // manual alignment
105105 inc(PByte(Station));
106106 SetLength(StationHash, HASHSIZE);
107107end ;
108108
109109{ $ifdef CUSTOMASM}
110110
111- function crc32c (buf: PAnsiChar; len: cardinal): PtrUInt; nostackframe; assembler;
111+ function dohash (buf: PAnsiChar; len: cardinal): PtrUInt; nostackframe; assembler;
112112asm
113113 xor eax, eax // it is enough to hash up to 15 bytes for our purpose
114114 mov ecx, len
@@ -130,7 +130,7 @@ function crc32c(buf: PAnsiChar; len: cardinal): PtrUInt; nostackframe; assembler
130130@z:
131131end ;
132132
133- function MemEqual (a, b: pointer; len: PtrInt): integer ; nostackframe; assembler;
133+ function CompareMem (a, b: pointer; len: PtrInt): boolean ; nostackframe; assembler;
134134asm
135135 add a, len
136136 add b, len
@@ -164,9 +164,18 @@ function MemEqual(a, b: pointer; len: PtrInt): integer; nostackframe; assembler;
164164 mov al, byte ptr [a + len]
165165 cmp al, byte ptr [b + len]
166166 je @eq
167- @diff: mov eax, 1
167+ @diff: xor eax, eax
168168 ret
169- @eq: xor eax, eax // 0 = found (most common case of no hash collision)
169+ @eq: mov eax, 1 // = found (most common case of no hash collision)
170+ end ;
171+
172+ { $else}
173+
174+ function dohash (buf: PAnsiChar; len: cardinal): PtrUInt; inline;
175+ begin
176+ if len > 16 then
177+ len := 16 ; // it is enough to hash up to 16 bytes for our purpose
178+ result := DefaultHasher(0 , buf, len); // fast mORMot asm hasher (crc32c)
170179end ;
171180
172181{ $endif CUSTOMASM}
@@ -176,16 +185,15 @@ function TBrcList.Search(name: pointer; namelen: PtrInt): PBrcStation;
176185 h, x: PtrUInt;
177186begin
178187 assert(namelen <= SizeOf(TBrcStation.NameText));
179- h := crc32c( { $ifndef CUSTOMASM } 0 , { $endif } name , namelen);
188+ h := dohash( name , namelen);
180189 repeat
181190 h := h and (HASHSIZE - 1 );
182191 x := StationHash[h];
183192 if x = 0 then
184193 break; // void slot
185194 result := @Station[x - 1 ];
186195 if (result^.NameLen = namelen) and
187- ({ $ifdef CUSTOMASM} MemEqual{ $else} MemCmp{ $endif} (
188- @result^.NameText, name , namelen) = 0 ) then
196+ CompareMem(@result^.NameText, name , namelen) then
189197 exit; // found
190198 inc(h); // hash collision: try next slot
191199 until false;
@@ -460,7 +468,7 @@ function ByStationName(const A, B): integer;
460468 result := sa.NameLen - sb.NameLen;
461469end ;
462470
463- function Average (sum, count: PtrInt): integer ;
471+ function Average (sum, count: PtrInt): PtrInt ;
464472// sum and result are temperature * 10 (one fixed decimal)
465473var
466474 x, t: PtrInt; // temperature * 100 (two fixed decimals)
0 commit comments