Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Funktion optimieren (https://www.delphipraxis.net/100778-funktion-optimieren.html)

xtZ 3. Okt 2007 19:50


Funktion optimieren
 
Hallo,

Ich habe folgende Funktion, die sehr oft aufgerufen wird und wüsste gerne, ob man die irgendwie optimieren kann mit ASM oder so.
Delphi-Quellcode:
function TestFunc(const s: String): Boolean; Inline;
var
  i, l: Integer;
begin
  Result := True;
  l := Length(s);
  if l <> 32 then
  begin
    Result := False;
    Exit;
  end;
  for i := 1 to l do
    if not (s[i] in ['0'..'9', 'A'..'f', 'a'..'f']) then
    begin
      Result := False;
      Break;
    end;
end;
Danke

MfG

Nikolas 3. Okt 2007 20:24

Re: Funktion optimieren
 
Wie kommen denn die Strings in dein Programm? Wie oft wird die Funktion aufgerufen? Kannst du nicht schon bei der Eingabe für diese Konfiguration sorgen?

Mackhack 3. Okt 2007 20:30

Re: Funktion optimieren
 
Delphi-Quellcode:
for i := 1 to l do
:wiejetzt:

Ultimator 3. Okt 2007 20:32

Re: Funktion optimieren
 
Zitat:

Zitat von Mackhack
Delphi-Quellcode:
for i := 1 to l do
:wiejetzt:

Das eine is ne Eins und das andere is ein "L". Passt schon soweit ich das überblicke ;)

OldGrumpy 3. Okt 2007 20:32

Re: Funktion optimieren
 
Zitat:

Zitat von xtZ
Hallo,

Ich habe folgende Funktion, die sehr oft aufgerufen wird und wüsste gerne, ob man die irgendwie optimieren kann mit ASM oder so.
Delphi-Quellcode:
function TestFunc(const s: String): Boolean; Inline;
[...]
  if not (s[i] in ['0'..'9', 'A'..'f', 'a'..'f']) then
[...]
Danke

MfG

Da hätte ich schonmal ne schöne Optimierung, benutze 'A'..'F' statt 'A'..'f' (Tippfehler?). Ausserdem könnte man mal schauen ob ein Aufruf von Uppercase() schneller ist als die Variante mit zwei Buchstabenmengen und in-Operator.

Dax 3. Okt 2007 20:33

Re: Funktion optimieren
 
Zitat:

Zitat von Mackhack
Delphi-Quellcode:
for i := 1 to L do

Delphi-Quellcode:
function TestFunc(const s: String): Boolean; Inline;
var
  i, l: Integer;
  c: char;
begin
  Result := True;
  l := Length(s);
  if l <> 32 then
  begin
    Result := False;
    Exit;
  end;
  for i := 1 to l do
  begin
    c := s[i];
    if (c <= '0' and c >= '9') or (c <= 'A' and C >= 'F') or (c <= 'a' and c >= 'f') then
    begin
      Result := False;
      Break;
    end;
  end;
end;
Das sollte (denke ich) schneller sein, da es die Set-Behandlung umgeht, die sich intern auf vergleichsweise riesige Datenstrukturen stützt. Wie Delphi deinen Code genau umsetzt, weiß ich allerdings nicht.

xtZ 3. Okt 2007 20:33

Re: Funktion optimieren
 
Zitat:

Zitat von Nikolas
Wie kommen denn die Strings in dein Programm? Wie oft wird die Funktion aufgerufen? Kannst du nicht schon bei der Eingabe für diese Konfiguration sorgen?

Ich lese zum Beispiel eine Datei zeilenweise ein und prüfe jede Zeile mit dieser Funktion.
Sehr oft. Die Datei(en) können schonmal mehrere Tausend Zeilen haben.
Nein.

sirius 3. Okt 2007 20:39

Re: Funktion optimieren
 
Für die For-Schleife fällt mir keine Abkürzung ein. Auch ASM wird da nicht mehr viel nützen. So schlecht ist der Delphi-Compiler nicht, dass man mit ASM noch etwas rausholen könnte. Du könntest noch den Aufruf der length-Funktion rausnehmen indem du direkt
Delphi-Quellcode:
if pcardinal(integer(s)-4)^ <> 32 then
abfragts, was allerdings eine AV gibt, wenn s leer ist. Ob das allerdings wirklich ein Zeitgewinn ist, weis ich nicht.


[rote Kästen]@Dax
Deine For-Schleife dürfte auf Grund der vielen Verglieche deutlich länger dauern. So ein Set geht schneller.

xtZ 3. Okt 2007 20:48

Re: Funktion optimieren
 
Erstmal Danke für die vielen Antworten.

@OldGrumpy
Ja es war ein Tippfehler :wink:
Uppercase und Lowercase bringt aber leider nicht wirklich was.

@dax
Bei deiner Methode ist irgendwas falsch (E2015 Operator ist auf diesen Operandentyp nicht anwendbar)

alzaimar 3. Okt 2007 20:56

Re: Funktion optimieren
 
Zitat:

Zitat von Dax
Das sollte (denke ich) schneller sein,

Nö, eher langsamer.
Zitat:

Zitat von Dax
da es die Set-Behandlung umgeht, die sich intern auf vergleichsweise riesige Datenstrukturen stützt. Wie Delphi deinen Code genau umsetzt, weiß ich allerdings nicht.

Findest Du 8 Bytes pro Set 'riesig'? :zwinker:

Ich finde das hier (getestet, ca 2x) schneller:
Delphi-Quellcode:
Var
  FraudChars : Array [Char] Of Boolean;

Procedure InitComparison;
Var
  c : Char;

Begin
  FillChar (FraudChars, SizeOf(FraudChars),0);
  for c:='0' to '9' do FraudChars[c] := True;
  for c:='a' to 'f' do FraudChars[c] := True;
  for c:='A' to 'F' do FraudChars[c] := True;
End;

function TestFunc(const s: String): Boolean; Inline;
var
  i, l: Integer;
  c: char;
begin
  Result := True;
  l := Length(s);
  if l <> 32 then
  begin
    Result := False;
    Exit;
  end;
  for i := 1 to l do
  begin
    If FraudChar [s[i]] Then Begin
      Result := False;
      Break;
    end;
  end;
end;
Du musst einmalig eine Lookuptabelle erstellen ('InitComparison') und dann diese verwenden. Alternativ kannst Du natürlich das Array als 'CONST' deklarieren.

Lookuptabellen sind eigentlich immer schneller (eigentlich = Ausnahmen bestätigen die Regel).

Bei solchen Problemen ist es immer wieder interessant, die Dinge auszutesten, weil man mit den Überlegungen häufig daneben liegt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:37 Uhr.
Seite 1 von 4  1 23     Letzte »    

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