Einzelnen Beitrag anzeigen

AlphaBug

Registriert seit: 2. Mär 2004
Ort: hinterm Transistor 246 gleich links
46 Beiträge
 
Delphi 6 Enterprise
 
#1

Merkwürdig ... oder ein Fehler meinerseits?

  Alt 13. Feb 2007, 20:09
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?
Delphi 4ever !
  Mit Zitat antworten Zitat