Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi MyStrToHex extrem schnell (https://www.delphipraxis.net/172301-mystrtohex-extrem-schnell.html)

PeterPanino 23. Dez 2012 23:15

Delphi-Version: XE2

MyStrToHex extrem schnell
 
Hallo! Ich möchte folgende Funktion auf extreme Geschwindigkeit optimieren:
Delphi-Quellcode:
function MyStrToHex(s: string): string;
var
  i: Integer;
begin
  Result := '';
  for i := 1 to Length(s) do
    Result := Result + IntToHex(Ord(s[i]), 4);
end;
Kennt jemand eine Assembler-Version davon?

Bernhard Geyer 23. Dez 2012 23:20

AW: MyStrToHex extrem schnell
 
Du brauchst keine Assembler um zu beschleunigen

1, Ergänze ein const beim Aufrufparameter
2, Verwende den Stringbuilder den es in neueren Delphiversionen gibt.

PeterPanino 24. Dez 2012 00:30

AW: MyStrToHex extrem schnell
 
Meinst etwa so?:
Delphi-Quellcode:
function MyStrToHex(const s: TStringBuilder): TStringBuilder;
var
  i: Integer;
begin
  Result := TStringBuilder.Create;
  for i := 0 to s.Length - 1 do
    Result.Append(IntToHex(Ord(s.Chars[i]), 4));
end;

SB := TStringBuilder.Create;
SB.Append('Tᾯest');
SB := MyStrToHex(SB);
Self.Caption := SB.ToString;
SB.Free;
Aber damit scheint der Code nicht schneller, sondern eher langsamer geworden zu sein.

Außerdem mache ich mir Sorgen: Muss die in der Funktion MyStrToHex in Result erzeugte StringBuilder-Instanz nicht irgendwie freigegeben werden?

Medium 24. Dez 2012 01:12

AW: MyStrToHex extrem schnell
 
Wie wäre es damit:

Delphi-Quellcode:
function MyStrToHex(const s: string): string;
var
   i: Integer;
begin
   SetLength(Result, Length(s)*4);
   for i := 0 to Length(s)-1 do
     Move(IntToHex(Ord(s[i+1]), 4), Result[i*4+1], 4);
end;
Ich habe gerade kein Delphi zur Hand, eventuell ließe sich IntToHex() noch effizienter implementieren und inlinen.

Bernhard Geyer 24. Dez 2012 08:31

AW: MyStrToHex extrem schnell
 
Zitat:

Zitat von PeterPanino (Beitrag 1196589)
Meinst etwa so?:

Für die Methodensignatur kannst du weiter Strings nehmen.
Nur beim Zusammenbauen des Strings den Stringbuilder nehmen:

Delphi-Quellcode:
function MyStrToHex(const s: String): String;
var
  i: Integer;
  StrBuilder: TStringBuilder;
begin
  StrBuilder := TStringBuilder.Create;
  try
    for i := 0 to s.Length - 1 do
      StrBuilder.Append(IntToHex(Ord(s[i]), 4));

    result := STrBuilder.ToString;
  finally
    StrBuilder.Free;
  end;
end;
Ansonsten probier Medium's Version.

Uwe Raabe 24. Dez 2012 09:08

AW: MyStrToHex extrem schnell
 
Kein Assembler, aber trotzdem recht schnell:

Delphi-Quellcode:
function MyStrToHex(const s: string): string;
const
  hex: array[0..15] of WideChar = '0123456789ABCDEF';
var
  I: Integer;
  W: WordRec;
  P: PChar;
begin
  SetLength(Result, 4*Length(S));
  P := PChar(Result);
  for I := 1 to Length(S) do
  begin
    W := WordRec(S[I]);
    P[0] := hex[W.Hi shr 4];
    P[1] := hex[W.Hi and $F];
    P[2] := hex[W.Lo shr 4];
    P[3] := hex[W.Lo and $F];
    Inc(P, 4);
  end;
end;

Furtbichler 24. Dez 2012 09:09

AW: MyStrToHex extrem schnell
 
IntToHex sollte sich optimieren lassen, z.B. über eine Lookuptabelle.

PeterPanino 24. Dez 2012 09:11

AW: MyStrToHex extrem schnell
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1196602)
Zitat:

Zitat von PeterPanino (Beitrag 1196589)
Meinst etwa so?:

Für die Methodensignatur kannst du weiter Strings nehmen.
Nur beim Zusammenbauen des Strings den Stringbuilder nehmen:

Delphi-Quellcode:
function MyStrToHex(const s: String): String;
var
  i: Integer;
  StrBuilder: TStringBuilder;
begin
  StrBuilder := TStringBuilder.Create;
  try
    for i := 0 to s.Length - 1 do
      StrBuilder.Append(IntToHex(Ord(s[i]), 4));

    result := STrBuilder.ToString;
  finally
    StrBuilder.Free;
  end;
end;
Ansonsten probier Medium's Version.

Du meintest wahrscheinlich so:
Delphi-Quellcode:
function MyStrToHex(s: string): string;
var
  i: Integer;
  SB: TStringBuilder;
begin
  Result := '';
  SB := TStringBuilder.Create;
  try
    for i := 1 to Length(s) do
      SB.Append(IntToHex(Ord(s[i]), 4));
    Result := SB.ToString;
  finally
    SB.Free;
  end;
end;
Vielen Dank für den Tipp! Gibt es aber eine Erklärung dafür, wieso TStringBuilder.Append schneller sein soll als das traditionelle Zusammenfügen von Strings mit dem Additionszeichen?

PeterPanino 24. Dez 2012 09:34

AW: MyStrToHex extrem schnell
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1196605)
Kein Assembler, aber trotzdem recht schnell:

Delphi-Quellcode:
function MyStrToHex(const s: string): string;
const
  hex: array[0..15] of WideChar = '0123456789ABCDEF';
var
  I: Integer;
  W: WordRec;
  P: PChar;
begin
  SetLength(Result, 4*Length(S));
  P := PChar(Result);
  for I := 1 to Length(S) do
  begin
    W := WordRec(S[I]);
    P[0] := hex[W.Hi shr 4];
    P[1] := hex[W.Hi and $F];
    P[2] := hex[W.Lo shr 4];
    P[3] := hex[W.Lo and $F];
    Inc(P, 4);
  end;
end;

Vielen Dank für den Tipp! Diese Version ist tatsächlich noch schneller als die StringBuilder-Version!

Ich habe mir auch überlegt, ob man den Schleifeninhalt nicht etwa in eine inline-Funktion auslagern kann, um die Geschwindigkeit nochmal zu steigern, sehe aber keine Möglichkeit dafür.

PeterPanino 24. Dez 2012 09:47

AW: MyStrToHex extrem schnell
 
Für die Umkehrfunktion verwende ich folgende Konstruktion:
Delphi-Quellcode:
function MyStrToIntSafe(const Value: string; const ExceptionResult: Integer): Integer; inline;
begin
  try
    Result := StrToInt(Value);
  except
    Result := ExceptionResult;
  end;
end;

function MyHexToChar(const s: string; const i: Integer): Char; inline;
begin
  Result := Chr(MyStrToIntSafe('$' + Copy(s, i, 4), 63));
end;

function MyHexToStr(s: string): string;
var
  i, L: Integer;
begin
  Result := '';
  L := Length(s);
  i := 1;
  while i < L do
  begin
    Result := Result + MyHexToChar(s, i);
    Inc(i, 4);
  end;
end;
Hier habe ich durch Auslagerung von Schleifeninhalten in inline-Funktionen nochmals eine Geschwindigkeitssteigerung erreicht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:57 Uhr.
Seite 1 von 3  1 23      

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