![]() |
Re: ReverseString für ältere Delphi-Versionen
@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:
Die Angaben sind CPU-Ticks.
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; Gemessen wurde auf Basis eines Strings mit 10 Zeichen.
Code:
zu letzterer sei angemerkt, dass diese Routine eine Prozedur ist, der Vergleich mit den Funktionen ist also nicht ganz fair.
#1 von Wolfgang Mix : 12650
#2 von jfheins : 450 #4 von himitsu : 280 #7 von turboPASCAL : 11660 #11 von amateurprofi : 45 |
Re: ReverseString für ältere Delphi-Versionen
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:
Bei Längen > 3 funktioniert die Routine zwar, aber dafür funktioniert danach irgend etwas anderes nicht mehr.
SHR ECX, 2
XOR EAX, EAX @@Loop4: MOV EDX, [ESI + EAX * 4] BSWAP EDX MOV [EDI + ECX * 4], EDX INC EAX LOOP @@Loop4 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; |
Re: ReverseString für ältere Delphi-Versionen
Ups, das mit EDI und ESI hatte ich ganz vergessen :oops: (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ß :shock: Joat und das stord/storb macht sich auch besser, wenn man eh schon esi/edi verwendet :thumb: |
Re: ReverseString für ältere Delphi-Versionen
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.... |
Re: ReverseString für ältere Delphi-Versionen
:shock:
Also bei INC/DEC hätte ich es genau andersrum gedacht, da dese doch eigentlikch weniger machen, im Gegensatz zum ADD/SUB :gruebel: (nja, ich hab 'nen AMD und keinen Intel :mrgreen: ) und beim LOOP hätte ich mindestens fast gleich schnell erwartet. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:31 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz