Einzelnen Beitrag anzeigen

Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
 
Delphi XE2 Professional
 
#7

AW: Doppel schnell aus Lise löschen.

  Alt 8. Dez 2014, 02:57
Versuch es mal so:

Bei ca. 100000 Einträgen wird am Schluss ca. 100000*100000 mal SameValue aufgerufen.
Die Idee ist, in TFloatPoints.InList, wiederholtes laden des Items (das mit allen Einträgen der Liste verglichen wird) und Epsilon in die FPU Register zu vermeiden und auch die Zugriffe auf die Items der Liste zu beschleunigen.
Ein kurzer Test verlief erfolgreich.
Ich habe 1000 Einträge mit Zufallswerten von X und Y im Bereich 0 bis 9 erzeugt.
Somit können nur max 100 verschiedene Einträge vorhanden sein.
Nach Aufruf von RemoveDuplicates enthielt die Liste dann auch 100 statt vorher 1000 Einträge.
Auf das Clear für "gelöschte" Einträge habe ich verzichtet, denn erstens kann auf diese Einträge eh nicht zugegriffen werden (bzw. sollte nicht zugegriffen werden können) und zweitens weiß ich nicht, was Clear macht. Ich vermute TFloatPoint.Clear setzt X und Y = 0. Da aber X=0 und Y=0 auch gültige Koordinaten sind, sehe ich da keine Vorteile.

Ich habe übrigens ein
type TAFloatPoint=Array of TFloatPoint; eingefügt und die Definition von FItems auf
FItems:TAFloatPoint; geändert.


Delphi-Quellcode:
procedure TFloatPoints.RemoveDoubles;

FUNCTION InList(List:TAFloatPoint; const Item:TFloatPoint; Count:Integer):Boolean;
const Epsilon:Double=1E-4;
asm
            fld Epsilon // st0=Epsilon
            fld QWord [edx] // st0=X, st1=Epsilon
            fld QWord [edx+8] // st0=Y, st1=X, st2=Epsilon
@Loop: fld QWord [eax] // st0=List.X, st1=Y, st2=X, st3=Epsilon
            fsub st,st(2) // st0=List.X-X
            fabs
            fcomip st,st(3) // List.X-X vs. Epsilon
            ja @Next // Verschieden (Abs(List.X-X) > Epsilon)
            fld QWord [eax+8] // st0=List.Y, st1=Y, st2=X, st3=Epsilon
            fsub st,st(1) // st0=List.Y-Y
            fabs
            fcomip st,st(3) // List.X-X vs. Epsilon
            jbe @True // Gleich (Abs(List.X-X) <= Epsilon)
@Next: add eax,16
            sub ecx,1
            jnz @Loop
            xor al,al
            jmp @End
@True: mov al,1
@End: ffree st(2)
            ffree st(1)
            ffree st
end;
var
   I,J: integer;
begin
   if FCount<2 then Exit;
   J:=1;
   for I:=1 to FCount-1 do
      if not InList(FItems,FItems[I],J) then begin
         FItems[J]:=FItems[I];
         Inc(J);
      end;
   FCount:=J
end;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat