Einzelnen Beitrag anzeigen

Amateurprofi

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

AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert

  Alt 19. Jul 2011, 00:44
Hallo hoika,
ich hatte vor einer Zeit das gleiche Problem und hatte zur Lösung eine kleine Routine geschrieben.
Es hat etwas gedauert aber ich hab sie jetzt wiedergefunden.
Die zweite Funktion ist "pure Pascal" und ist entsprechend langsamer.

Um die Performance zu testen habe ich einen String mit der Länge 100 Mio komplett mit 'A's gefüllt,
dann an 2 Mio zufälligen Positionen #10 bzw #13#10 eingestreut.
Ergebnis : 175 ms bzw. 375 ms (zweite Funktion).

Für einen Vergleich mit StringReplace(s,#10,#13#10,[rfReplaceAll]) habe ich einen String mit der Länge 1 Mio genommen und an 20000 Positionen #10 eigestreut.
StringReplace braucht 39 s, die beiden anderen < 15 ms.
Naja, kein ganz fairer Vergleich, weil StringReplace universell einsetzbar ist aber ich denke, daß die, die StringReplace geschrieben haben, sich die Sache etwas leicht gemacht haben.

Delphi-Quellcode:
FUNCTION EnsureCRLF(s:string):string;
FUNCTION Replace(dest,source:string):integer;
asm
         push eax
         push ebx
         mov bx,$0A0D // BL=CR, BH=LF
         jmp @Entry
@Char: mov [eax],cl
         add eax,1
@1: add edx,1
@Entry: mov cx,[edx] // 2 Chars aus Source
         cmp cx,bx
         je @CRLF
         cmp cl,bh
         je @LF
         test cl,cl
         jne @Char
         jmp @End
@LF: mov [eax],bx
         add eax,2
         jmp @1
@CRLF: mov [eax],bx
         add edx,2
         add eax,2
         jmp @Entry
@End: pop ebx
         pop ecx
         sub eax,ecx
end;
//------------------------------------------------------------------------------
var len:integer; dest:string;
begin
   if s='then exit;
   SetLength(result,Length(s)*2);
   SetLength(result,Replace(result,s));
end;

Delphi-Quellcode:
FUNCTION xEnsureCRLF(var s:string):string;
FUNCTION Replace(var dest:string; const source:string):integer;
var ps,pd,pdsave:PChar;
begin
   ps:=@source[1];
   pd:=@dest[1];
   pdsave:=pd;
   repeat
      case ps^ of
         #10 : begin
                     PWord(pd)^:=$0A0D;
                     inc(PWord(pd));
                     inc(ps);
                  end;
         #13 : if (ps+1)^=#10 then begin
                     PWord(pd)^:=$0A0D;
                     inc(PWord(pd));
                     inc(PWord(ps));
                  end else begin
                     pd^:=#13;
                     inc(pd);
                     inc(ps);
                  end;
         #0 : break;
         else begin
                     pd^:=ps^;
                     inc(pd);
                     inc(ps);
                  end;
      end;
   until false;
   result:=Integer(pd)-Integer(pdsave);
end;
//------------------------------------------------------------------------------
var len:integer; dest:string;
begin
   if s='then exit;
   SetLength(result,Length(s)*2);
   SetLength(result,Replace(result,s));
end;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat