AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TEdit + Steuerzeichen + XML = Exception

Ein Thema von Whookie · begonnen am 2. Jul 2025 · letzter Beitrag vom 4. Jul 2025
 
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.079 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: TEdit + Steuerzeichen + XML = Exception

  Alt 3. Jul 2025, 12:50
Na gut, es würde alles noch ein bisschen schneller gehen, wenn man bis zum Maximum optimiert:

Code:
Debug Output: Original TStringBuilder: 53,99 ms Process Project1.exe (27340)
Debug Output: Optimiert mit PChar: 48,4411 ms Process Project1.exe (27340)
Debug Output: Direkter Zugriff: 27,047 ms Process Project1.exe (27340)
Debug Output: Direkter Zugriff 2: 16,019 ms Process Project1.exe (27340)
Debug Output: Direkter Zugriff 3: 12,4765 ms Process Project1.exe (27340)
Delphi-Quellcode:
function SanitizeXML_Original(const AValue: String): String;
var
  i: Integer;
  LChr: Char;
  LStrBldr: TStringBuilder;
begin
  LStrBldr := TStringBuilder.Create;
  try
    for i := 1 to Length(AValue) do
    begin
      LChr := AValue[i];
      if (LChr = #9) or (LChr = #10) or (LChr = #13) or
         ((LChr >= #32) and (LChr <= #$D7FF)) or
         ((LChr >= #$E000) and (LChr <= #$FFFD)) then
        LStrBldr.Append(LChr);
    end;
    Result := LStrBldr.ToString;
  finally
    LStrBldr.Free;
  end;
end;

function SanitizeXML_PChar(const AValue: String): String;
var
  Src, SrcEnd: PChar;
  LStrBldr: TStringBuilder;
  C: Char;
begin
  LStrBldr := TStringBuilder.Create(Length(AValue));
  try
    Src := PChar(AValue);
    SrcEnd := Src + Length(AValue);
    while Src < SrcEnd do
    begin
      C := Src^;
      if (C = #9) or (C = #10) or (C = #13) or
         ((C >= #32) and (C <= #$D7FF)) or
         ((C >= #$E000) and (C <= #$FFFD)) then
        LStrBldr.Append(C);
      Inc(Src);
    end;
    Result := LStrBldr.ToString;
  finally
    LStrBldr.Free;
  end;
end;

function SanitizeXML_Direct(const AValue: String): String;
var
  Src: PChar;
  Dest: PChar;
  Len, i: Integer;
  C: Char;
begin
  Len := Length(AValue);
  SetLength(Result, Len);
  Src := PChar(AValue);
  Dest := PChar(Result);

  for i := 0 to Len - 1 do
  begin
    C := Src[i];
    if (C = #9) or (C = #10) or (C = #13) or
       ((C >= #32) and (C <= #$D7FF)) or
       ((C >= #$E000) and (C <= #$FFFD)) then
    begin
      Dest^ := C;
      Inc(Dest);
    end;
  end;

  SetLength(Result, Dest - PChar(Result));
end;

function SanitizeXML_Direct_2(const AValue: String): String;
var
  Src: PChar;
  Dest: PChar;
  Len, i: Integer;
  C: Char;
begin
  Len := Length(AValue);
  SetLength(Result, Len);
  Src := PChar(AValue);
  Dest := PChar(Result);

  for i := 0 to Len - 1 do
  begin
    C := Src[i];
    case C of
      #9, #10, #13, #32..#$D7FF, #$E000..#$FFFD:
      begin
        Dest^ := C;
        Inc(Dest);
      end;
    end;
  end;

  SetLength(Result, Dest - PChar(Result));
end;

function SanitizeXML_Direct_3(const AValue: String): String;
var
  Src, SrcEnd, Dest: PChar;
  Len: Integer;
begin
  Len := Length(AValue);
  SetLength(Result, Len);
  Src := PChar(AValue);
  Dest := PChar(Result);
  SrcEnd := Src + Len;

  while Src < SrcEnd do
  begin
    case Src^ of
      #9, #10, #13,
      #32..#$D7FF,
      #$E000..#$FFFD:
      begin
        Dest^ := Src^;
        Inc(Dest);
      end;
    end;
    Inc(Src);
  end;

  SetLength(Result, Dest - PChar(Result));
end;

procedure RunBenchmark;
const
  Iterations = 1000;
var
  i: Integer;
  InputStr, ResultStr1, ResultStr2, ResultStr3, ResultStr4, ResultStr5: String;
  SW: TStopwatch;
begin
  // Beispiel-XML mit gültigen/ungültigen Zeichen
  InputStr := StringOfChar('A', 10000) + #0 + #1 + #2 + #3 + #4 + #5 + #6 + #7 +#8 + #$FFFF + StringOfChar('B', 10000);

  // Original
  SW := TStopwatch.StartNew;
  for i := 1 to Iterations do
    ResultStr1 := SanitizeXML_Original(InputStr);
  SW.Stop;
  OutputDebugString(PChar('Original TStringBuilder: ' + SW.Elapsed.TotalMilliseconds.ToString + ' ms'));

  // PChar + TStringBuilder
  SW := TStopwatch.StartNew;
  for i := 1 to Iterations do
    ResultStr2 := SanitizeXML_PChar(InputStr);
  SW.Stop;
  OutputDebugString(PChar('Optimiert mit PChar: ' + SW.Elapsed.TotalMilliseconds.ToString + ' ms'));

  // Direkte Speicherzugriffe
  SW := TStopwatch.StartNew;
  for i := 1 to Iterations do
    ResultStr3 := SanitizeXML_Direct(InputStr);
  SW.Stop;
  OutputDebugString(PChar('Direkter Zugriff: ' + SW.Elapsed.TotalMilliseconds.ToString + ' ms'));

  // Direkte Speicherzugriffe mit case-of
  SW := TStopwatch.StartNew;
  for i := 1 to Iterations do
    ResultStr4 := SanitizeXML_Direct_2(InputStr);
  SW.Stop;
  OutputDebugString(PChar('Direkter Zugriff 2: ' + SW.Elapsed.TotalMilliseconds.ToString + ' ms'));

  // Direkte Speicherzugriffe mit while statt for und mit case-of
  SW := TStopwatch.StartNew;
  for i := 1 to Iterations do
    ResultStr5 := SanitizeXML_Direct_3(InputStr);
  SW.Stop;
  OutputDebugString(PChar('Direkter Zugriff 3: ' + SW.Elapsed.TotalMilliseconds.ToString + ' ms'));
end;

Geändert von TiGü ( 3. Jul 2025 um 13:03 Uhr)
  Mit Zitat antworten Zitat
 


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 08:28 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