![]() |
XE2 Stringfunktion + ASM code : function CountString(...)
unter
![]() leider bei mir nicht mit Delphi XE2 compilierbar a) um prinzpiell im x32 und x64 bit mode zu kompilieren müssten doch die $IFDEF Definition richtig sein? b) keyword ASM erzeugt bei mir einen Fehler im x64 bit modus c) unter x32 bekomme ich folgenden Fehler [DCC Fehler] _faststrings.pas(1467): E2116 Ungültige Kombination von Opcode und Operanden (bei TEST &SubStr, &SubStr) ??
Delphi-Quellcode:
///
/// Counts number of substr in S /// source: [url]http://www.delphipraxis.net/51284-teil-string-anderem-string-suchen-zaehlen.html[/url] /// /// failure with XE2 compiler !!! function CountString(Const substr, s: AnsiString): Word; begin {$IFDEF CPUX86} ASM PUSH ESI PUSH EDI PUSH EBX TEST &SubStr, &SubStr JE @Exit TEST &S, &S JE @Exit0 MOV ESI, &SubStr MOV EDI, &S PUSH EDI MOV ECX, [EDI - 4] MOV EDX, [ESI - 4] DEC EDX JS @Fail XOR EAX, EAX MOV AL, [ESI] INC ESI SUB ECX, EDX JLE @Fail @Loop: REPNE SCASB JNE @Ready MOV EBX, ECX PUSH ESI PUSH EDI MOV ECX, EDX REPE CMPSB POP EDI POP ESI JNE @noInc CMP EAX, $FFFF0000 JAE @Ready ADD EAX, $00010000 @noInc: MOV ECX, EBX JMP @Loop @Fail: POP EDX @Exit0: XOR EAX, EAX JMP @Exit @Ready: POP EDX SHR EAX, 16 @Exit: POP EBX POP EDI POP ESI end; {$ENDIF CPUX86} /// x64 bit code {$IFDEF CPUX64} /// ???? asm end; {$ENDIF CPUX64} End; |
AW: XE2 Stringfunktion + ASM code : function CountString(...)
Ein paar [delphi]-Tags wären nicht schlech. :zwinker:
Delphi-Quellcode:
Geht unter 64 Bit garnicht mehr, da es dort kein Inline-Assemler mehr gibt (in Delphi).
begin
... ASM Prozeduren müssen entweder in Pascal oder Assembler geschrieben sein. (gemischt ist nicht mehr ... je Prozedur) also entweder
Delphi-Quellcode:
oder
function CountString(Const substr, s: WideString): Word;
{$IFDEF CPUX86} asm ... end; {$ENDIF CPUX86} {$IFDEF CPUX64} asm ... end; {$ENDIF CPUX64}
Delphi-Quellcode:
function CountString(Const substr, s: WideString): Word;
asm {$IFDEF CPUX86} ... {$ENDIF CPUX86} {$IFDEF CPUX64} ... {$ENDIF CPUX64} end; Du könntest dir die WideString-Varianten nehmen und müßtest unter Win64 die Register anpassen. Unter 32 Bit lagen die ersten Parameter in EAX, EDX, ECX, welche aber bei 64 Bit nun anders vereilt sind. Irgenwo wurde das hier, in der DP, vor Kurzem mal erwähnt. Für den Anfang also einfach nur die entsprechenden 32-Bit-Register der 64-Bit-Architektur verwenden. Wenn ich mal die Zeit finde, läßt sich dann bestimmt noch einiges Optimieren. (mit MMX, SSE und Co.) |
AW: XE2 Stringfunktion + ASM code : function CountString(...)
Zitat:
Zitat:
|
AW: XE2 Stringfunktion + ASM code : function CountString(...)
Warum das ganze überhaupt in Assembler? Das (die Quelle) sieht mir so aus als ob da "Assembler ist immer schneller als Pascal Code" gedacht wurde. Und dann auch noch "repnz scasb", was zu 80386-er Zeiten "relativ" schnell war aber mittlerweile besser mit einer loop gemacht wird.
|
AW: XE2 Stringfunktion + ASM code : function CountString(...)
Eine Nicht-Assmbler-Version könnte wohl so aussehn: (ungetestet)
Delphi-Quellcode:
eventuell auch so:
function CountString(const SubStr, S: String): Integer;
var i: Integer; begin Result := 0; i := 0; while True do begin i := PosEx(SubStr, S, i + 1); if i = 0 then Exit; Inc(Result); end; end; (weiß grade nicht, wie genau gezählt wurde ... ist/war CountString('xxx', 'xxxxxx') = 2 oder 4? )
Delphi-Quellcode:
function CountString(const SubStr, S: String): Integer;
var i: Integer; begin Result := 0; i := 1; while True do begin i := PosEx(SubStr, S, i); if i = 0 then Exit; Inc(i, Length(SubStr)); Inc(Result); end; end; |
AW: XE2 Stringfunktion + ASM code : function CountString(...)
Himiiii! "while true" und "Exit" - wo komms du denn her? ;)
Delphi-Quellcode:
function CountString(const SubStr, S: String): Integer;
var i: Integer; begin Result := 0; i := 0; repeat i := PosEx(SubStr, S, i + 1); if i > 0 then Inc(Result); // oder Inc(Result, IfThen(Result>0, 1, 0)); // Könnte nur langsamer sein until i = 0; end; |
AW: XE2 Stringfunktion + ASM code : function CountString(...)
Müsste i nicht vor der Schleife mit 0 initialisiert werden?
|
AW: XE2 Stringfunktion + ASM code : function CountString(...)
Ups :)
|
AW: XE2 Stringfunktion + ASM code : function CountString(...)
Einfacher/Optimierter Code?
Das True und den Jump-Befehl sollte Delphi auch noch wegoptimieren. Das Exit ist eigentlich ein Break, aber da hier nichts mehr nach der Schleife kommt... PS: siehe FastMM, EurekaLog, GNU gettext, FastReport, PgDAC, TMS Workflow, SynEdit, JCL und Delphi VCL ... überall findet man
Delphi-Quellcode:
:stupid:
while true do
|
AW: XE2 Stringfunktion + ASM code : function CountString(...)
Das ist zur Optimierung auch manchmal sinnvoll (wenn denn die Funktion wirklich so wichtig ist was die Geschwindigkeit angeht).
Aber das Exit in einer Zeile mit dem if zu verstecken ist richtig unsaubere Formatierung... Sorry, aber ist so... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:52 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 by Thomas Breitkreuz