AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Neuen Beitrag zur Code-Library hinzufügen Delphi ReverseString für ältere Delphi-Versionen
Thema durchsuchen
Ansicht
Themen-Optionen

ReverseString für ältere Delphi-Versionen

Ein Thema von Wolfgang Mix · begonnen am 11. Dez 2009 · letzter Beitrag vom 12. Dez 2009
Antwort Antwort
Seite 2 von 2     12   
Amateurprofi

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

Re: ReverseString für ältere Delphi-Versionen

  Alt 12. Dez 2009, 01:03
@Himitsu:
So ähnlich wollte ich auch antworten.
Ich hab mal getestet wie schnell/langsam die Routinen sind und habe auch noch eine eigene Routine dazu gestellt.

Delphi-Quellcode:
PROCEDURE ReverseStr(var s:string);
var p1,p2:PChar; c:Char;
begin
   if s='then exit;
   p1:=@s[1];
   p2:=p1+Length(s)-1;
   while p1<p2 do begin
      c:=p1^;
      p1^:=p2^;
      p2^:=c;
      inc(p1);
      dec(p2);
   end;
end;
Die Angaben sind CPU-Ticks.
Gemessen wurde auf Basis eines Strings mit 10 Zeichen.


Code:
#1 von Wolfgang Mix : 12650
#2  von jfheins     :  450
#4  von himitsu     :  280
#7  von turboPASCAL : 11660 
#11 von amateurprofi :   45
zu letzterer sei angemerkt, dass diese Routine eine Prozedur ist, der Vergleich mit den Funktionen ist also nicht ganz fair.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Amateurprofi

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

Re: ReverseString für ältere Delphi-Versionen

  Alt 12. Dez 2009, 19:25
Und nochmal @himitsu:

Die Systemroutinen kannst du mit z.B.
CALL System.@LStrSetLength
aufrufen.
Zu deiner Assembler Routine:
Hast du die mal getestet ?
Bei Längen im Bereich 1 bis 3 gibts Probleme.
Warum?:
ECX enthält Length(Text).
Wenn ECX<4 ist dann wird ECX durch SHR ECX,2 auf 0 gestellt.
Das Loop senkt dann ECX um 1 und springt zu @@Loop4, bis ECX=0 ist.
Die Schleife wird also 2^32 mal durchlaufen, bzw. bis es 'ne Exception gibt.
Delphi-Quellcode:
    SHR ECX, 2
    XOR EAX, EAX
    @@Loop4:
    MOV EDX, [ESI + EAX * 4]
    BSWAP EDX
    MOV [EDI + ECX * 4], EDX
    INC EAX
    LOOP @@Loop4
Bei Längen > 3 funktioniert die Routine zwar, aber dafür funktioniert danach irgend etwas anderes nicht mehr.
Warum ?: Weil du EDI und ESI veränderst.

Ich hab die Idee mit dem bswap aufgegriffen.
Delphi-Quellcode:
FUNCTION ReverseStr_A(s:string):string;
asm
         test eax,eax
         jne @Start
         mov eax,edx
         jmp system.@LStrClr
@Start: push edi
         mov edi,edx
         push eax
         mov edx,[eax-4]
         mov eax,edi
         call System.@LStrSetLength
         pop edx     // @s[1]
         mov ecx,[edx-4] // Length(s)
         mov edi,[edi] // @result[1]
         jmp @NextDW
@DWLoop: mov eax,[edx+ecx]
         bswap eax
         stosd
@NextDW: sub ecx,4
         jnc @DWLoop
         add ecx,3
         js @End
@BLoop: mov al,[edx+ecx]
         stosb
         sub ecx,1
         jnc @BLoop
@End: pop edi
end;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.056 Beiträge
 
Delphi 12 Athens
 
#13

Re: ReverseString für ältere Delphi-Versionen

  Alt 12. Dez 2009, 20:00
Ups, das mit EDI und ESI hatte ich ganz vergessen (dachte die waren so wie EAX, EDX und ECX)
joar, und das mit dem <4 stimmt

hab es oben mal geändert



für "sub ecx,1" würde wohl auch "dec ecx" gehn
und

"loop @BLoop" entspricht einem "dec ecx; jnz @BLoop", aber ich weiß hier nicht, welches optimaler arbeitet

"call @LStrSetLength" hatte ich aber probiert und ich wäre nicht drauf gekommen, daß man den System-Namespace unbedingt verwenden muß

Joat und das stord/storb macht sich auch besser, wenn man eh schon esi/edi verwendet
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Amateurprofi

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

Re: ReverseString für ältere Delphi-Versionen

  Alt 12. Dez 2009, 20:32
Intel empfiehlt statt INC xxx / DEC xxx besser ADD xxx,1 / SUB xxx,1 zu verwenden (weil schneller).
Und LOOP ist deutlich langsamer als SUB ECX,1; JNZ .
Deshalb ist die von mir gezeigte Version auch erheblich schneller....
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.056 Beiträge
 
Delphi 12 Athens
 
#15

Re: ReverseString für ältere Delphi-Versionen

  Alt 12. Dez 2009, 20:47


Also bei INC/DEC hätte ich es genau andersrum gedacht, da dese doch eigentlikch weniger machen, im Gegensatz zum ADD/SUB
(nja, ich hab 'nen AMD und keinen Intel )

und beim LOOP hätte ich mindestens fast gleich schnell erwartet.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz