[fpc-devel] CompareMem slower in FPC 2.4.4
José Mejuto
joshyfun at gmail.com
Thu Jun 2 18:45:23 CEST 2011
Hello FPC,
Wednesday, June 1, 2011, 10:07:18 PM, you wrote:
MK> In my tests, FPC 2.4.4 has much slower CompareMem than FPC 2.4.2, at
MK> least for some cases:
The difference is that CompareMem takes the same time to check a
memory block if the elements are equal or different, while the pascal
code aborts inmediatly after first difference.
I had performed a fast test filling 2 megabytes of memory, the first
with value "1" and the second with value "2". Performing the test 10
millions times takes 610 milliseconds. In the second test fill both
arrays with same value, and CompareMem takes 610 milliseconds.
After some tests (not very professional) CompareMem takes much more
advantage if the amount of bytes to be compared are more than 32-38, so
the best performance I get is using this function:
function XCompareByte(const p1,p2,Length: sizeInt): SizeInt;
var
j: SizeInt;
PB1: PBYTE absolute p1;
PB2: PBYTE absolute p2;
begin
if Length<=38 then begin
for j := 0 to Length-1 do begin
if pb1[j]<>PB2[j] then begin
Result:=BYTE(PB1[j]-PB2[j]);
exit;
end;
end;
Result:=0;
end else begin
Result:=CompareByte(p1,p2,Length);
end;
end;
In my computer Intel 9300 QCore WindowsXP this function get the best
of the two worlds, fast comparison escape for different memory blocks,
fast compare for small blocks and the "rep cmpsl" for larger blocks,
performance that can not be achieved with the pascal loop. The
comparison penalty if rapidly payed with the fast escape in case of
differeces in the very first bytes.
I'm quite sure the magic number is 32 not 38, but in my case I get
better performance with 38.
Simple test code:
procedure Comparememtest;
const
COMPARELENGTH=1000;
var
p1,p2: PBYTE;
j: integer;
ST,ET: TTimeStamp;
begin
GetMem(p1,1000000);
for j := 0 to 1000000-1 do begin
p1[j]:=0;
end;
GetMem(p2,1000000);
for j := 0 to 1000000-1 do begin
p2[j]:=0;
end;
ST:=DateTimeToTimeStamp(Now);
for j := 0 to 10000000 do begin
XCompareByte(SizeInt(p1),SizeInt(p2),COMPARELENGTH);
end;
ET:=DateTimeToTimeStamp(Now);
self.Caption:=inttostr(ET.Time-ST.Time);
FreeMem(p1);
FreeMem(p2);
end;
Times table:
PlainCompare CompareByte XCompareByte
------------ ----------- ------------
Equal arrays 1000 elements 16250 ms 625 ms 656 ms
Diff. arrays 1000 elements 62 ms 640 ms 656 ms
Equal arrays 32 elements 547 ms 625 ms 547 ms
Diff. arrays 32 elements 62 ms 640 ms 62 ms
--
Best regards,
José
More information about the fpc-devel
mailing list