Hallo,
ich habe eine eigene Variante der
VCL-Klasse TList namens TgeBaseList erstellt.
Diese Klasse wollte ich erweitern und optimieren.
Dabei habe ich mir auch die Klasse TPersistentObjectList aus dem GLScene-
Package angesehen.
In der Hilfe von GLScene wird angegeben, dass die Implementierung der IndexOf-Funktion der Klasse TPersistentObjectList bis zu drei mal schneller sei, als Die der TList-Klasse.
Nun habe ich den Quellcode der Funktion in meine Klasse "übernommen".
Wenn ich jetzt Zeitmessungen durchführe muss ich jedoch feststellen, dass Sie nicht schneller sondern langsamer ist
als die TList.
Hier mein (schnellerer) Code
(Wird so auch in TList verwendet):
Delphi-Quellcode:
function TgeBaseList.IndexOf(Item: gePointer): geInteger;
begin
Result := 0;
while (Result < Self.fCount) and
(Self.fList^[Result] <> Item) do
System.Inc(Result);
if (Result = Self.fCount) then
Result := (-1);
end;
Hier der Code aus GLScene
(der angeblich bis zu 3x so schnell sei):
Delphi-Quellcode:
function TPersistentObjectList.IndexOf(Item: TObject): Integer;
var
c : Integer;
p : ^TObject;
begin
if FCount<=0
then
Result:=-1
else begin
c:=FCount;
p:=@FList^[0];
asm
mov eax, Item;
mov ecx, c;
mov edx, ecx;
push edi;
mov edi, p;
repne scasd;
je @@FoundIt
mov edx, -1;
jmp @@SetResult;
@@FoundIt:
sub edx, ecx;
dec edx;
@@SetResult:
mov Result, edx;
pop edi;
end;
end;
end;
Daraus habe ich dann eine Umsetzung komplett in Assembler erstellt
(die aber langsamer ist als die Delphi-Variante von TList):
Delphi-Quellcode:
function TgeBaseList.IndexOf(Item: gePointer): geInteger;
{ EAX=Self EDX=Item ; Result=EAX }
asm
PUSH EDI
{EDI := @fList^[0];}
MOV ECX, TgeBaseList(EAX).fList
LEA EDI, [ECX]
{ECX is Counter}
MOV ECX, TgeBaseList(EAX).fCount
{EAX := Item}
MOV EAX, EDX
{EDX is Result-Buffer}
MOV EDX, ECX
{Scan for Item}
REPNE SCASD
JE @@Found
{ not Found -> Result := -1 }
MOV EDX, -1
JMP @@Done
@@Found:
SUB EDX, ECX
DEC EDX
@@Done:
MOV EAX, EDX
POP EDI
end;
Kann mir das jemand erklären?
Habe ich vielleicht etwas falsch gemacht?