Delphi-PRAXiS

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.

xtZ 3. Okt 2007 21:11

Re: Funktion optimieren
 
Hi alzaimar,

Deine Methode ist zwar sehr schnell, aber sie funktioniert (bei mir) nicht. :?
Hab das "InitComparison" im Formcreate Ereignis eingefügt und die procedure ersetzt und es kommt immer als Result "False" raus.

//Edit:
Habs, du hattest ein "not" vor FraudChars vergessen.

x000x 4. Okt 2007 01:10

Re: Funktion optimieren
 
Moin moin,
die Zuweisung zu L kann doch weggelassen werden...
Delphi-Quellcode:
//..
  if Length(s) <> 32 then
  begin
    Result := False;
    Exit;
  end;
  for i := 1 to 32 do
//..

WS1976 4. Okt 2007 06:28

Re: Funktion optimieren
 
Hallo Dax,
dieser Ausdruck ist falsch. Die Bedingung zum Rausfliegen ist schon erfüllt wenn c ausserhalb '0' bis '9' liegt.
Delphi-Quellcode:
    if (c <= '0' and c >= '9') or (c <= 'A' and C >= 'F') or (c <= 'a' and c >= 'f') then
Grüsse
Rainer

alzaimar 4. Okt 2007 06:49

Re: Funktion optimieren
 
Hi xtZ,

Hier nochmal eine Zusammenfassung (Fehler bereinigt, Optimierungen der Anderen eingebaut):
Delphi-Quellcode:
Var
  FraudChars : Array [Char] Of Boolean;

Procedure InitComparison;
Var
  c : Char;

Begin
  For c:=low(Char) To High (Char) Do FraudChars[c] := True;
  for c:='0' to '9' do FraudChars[c] := False;
  for c:='a' to 'f' do FraudChars[c] := False;
  for c:='A' to 'F' do FraudChars[c] := False;
End;

function TestFunc(const s: String): Boolean; Inline;
var
  i : Integer;
 
begin
  Result := True;
  if Length(s) <> 32 then
    Result := False
  else for i := 1 to 32 do
    If FraudChar [s[i]] Then Begin
      Result := False;
      Break;
    end;
  end;
end;

WS1976 4. Okt 2007 08:11

Re: Funktion optimieren
 
Hallo,
so verstehts auch jeder:

Delphi-Quellcode:
function TestFunc(const s: String): Boolean; Inline;
var
  i : Integer;
 
begin
  Result := True;
  if Length(s) <> 32 then
    Result := False
  else
    for i := 1 to 32 do
       If FraudChar [s[i]] Then
          Begin
            Result := False;
            Break;
          end;
end;
Grüsse
Rainer

alzaimar 4. Okt 2007 08:13

Re: Funktion optimieren
 
Zitat:

Zitat von WS1976
so verstehts auch jeder

Stimmt. Dank Deiner professionellen Hilfe ist aus meinem Amateurgefrickel endlich lesbarer Code geworden. :zwinker:

Wobei man ja geteilter Meinung über die Formatierung sein kann, gelle?

Sidorion 4. Okt 2007 08:28

Re: Funktion optimieren
 
Richtig, alzimar. Das Einzige, was man vielleicht noch anders schreiben kann/möchte/sollte/haben/sein wäre diese Ecke:
Delphi-Quellcode:
  if Length(s) <> 32 then
    Result := False
Ich würde entweder die Anweisung hinten ans Then anhängen, oder das Then vor die Anweisung runterziehen, damit in 5 Jahren keiner auf die Idee kommt, da noch was hinzufrickeln.
Delphi-Quellcode:
  if Length(s) <> 32 then Result := False
// oder
  if Length(s) <> 32 
  then Result := False
@ws1976: nich böse sein, aber bei Deiner Schreibweise würde ich nie wissen, ob jetzt genügend ends da sind und wenn ja, ob sie an der richtigen Stelle sitzen.

RavenIV 4. Okt 2007 09:04

Re: Funktion optimieren
 
Zitat:

Zitat von Sidorion
Richtig, alzimar. Das Einzige, was man vielleicht noch anders schreiben kann/möchte/sollte/haben/sein wäre diese Ecke:
Delphi-Quellcode:
  if Length(s) <> 32 then
    Result := False

Wenn dann aber schon so:
Delphi-Quellcode:
if Length(s) <> 32 then
begin
  Result := False;
end { if Length(s) }
else
begin
  for i := 1 to 32 do
  begin
    if FraudChar [s[i]] then
    Begin
      Result := False;
      Break;
    end; { if FraudChar }
  end; { for i }
end; { else if Length(s) }

OldGrumpy 4. Okt 2007 09:08

Re: Funktion optimieren
 
Ein kleines Quentchen (JA, alte Rechtschreibung, das Wort hat wohl überhaupt nichts mit Quant zu tun :P) kann man wohl noch einsparen indem man sich die Zuweisung "Result:=True" am Anfang spart und nur ausführt wenn die Länge passt, da ansonsten eh gleich wieder Result:=False gesetzt wird. Also ab damit in den Else-Zweig :)

xaromz 4. Okt 2007 09:15

Re: Funktion optimieren
 
Hallo,

wenn wir schon dabei sind, Zuweisungen zu vermeiden, dann gleich richtig:
Delphi-Quellcode:
function TestFunc(const s: String): Boolean; Inline;
var
  i: Integer;
begin
  Result := False;
  if Length(s) = 32 then
  begin
    for i := 1 to 32 do
       if FraudChar [s[i]] then
         Exit;
    Result := True;
  end;
end;
Wobei es hier ja um Geschwindigkeit geht, und die Zuweisung von Result das eax-Register blockiert. Deshalb sollte Result eigentlich nur am Ende der Funktion gesetzt werden. Das darf aber jemand anderes machen...

Gruß
xaromz

RavenIV 4. Okt 2007 09:25

Re: Funktion optimieren
 
Und schon wieder wird der Borland-Styleguide nicht beachtet. :warn:

Ich red mir hier in verschiedenen Threads den Mund fusselig und jeder schreibt weiterhin den Code, wie er es für richtig hält. :-(

xaromz 4. Okt 2007 09:38

Re: Funktion optimieren
 
Hallo,
Zitat:

Zitat von RavenIV
Und schon wieder wird der Borland-Styleguide nicht beachtet. :warn:

Ich red mir hier in verschiedenen Threads den Mund fusselig und jeder schreibt weiterhin den Code, wie er es für richtig hält. :-(

wo steht noch mal genau, dass jeder den Styleguide von Borland verwenden muss? Abgesehen davon: wo siehst Du ein Problem?

Verwunderte Grüße
xaromz

RavenIV 4. Okt 2007 09:49

Re: Funktion optimieren
 
Zitat:

Zitat von xaromz
wo steht noch mal genau, dass jeder den Styleguide von Borland verwenden muss? Abgesehen davon: wo siehst Du ein Problem?


Richtig. Niemand schreibt Dir vor, Dich an (irgendeinen) Styleguide zu halten.
Aber wenn man das vernünftig betrachtet sollte man es tun.

Und ich habe kein Problem.
Nur kommt mir jedesmal die Galle hoch, wenn ich sowas in dieser Art sehe:
Delphi-Quellcode:
    for i := 1 to 32 do
       if FraudChar [s[i]] then
         Exit;
    Result := True;
Aus diesem Grund würde Jemand, der MEINEN Styleguide (der auf dem Borland Styleguide basiert) in MEINER Abteilung permanent missachtet, erst eine Abmahnung und dann die Kündigung erhalten.

xaromz 4. Okt 2007 10:03

Re: Funktion optimieren
 
Hallo,
Zitat:

Zitat von RavenIV
Nur kommt mir jedesmal die Galle hoch, wenn ich sowas in dieser Art sehe:
Delphi-Quellcode:
    for i := 1 to 32 do
       if FraudChar [s[i]] then
         Exit;
    Result := True;

gut, aber wo ist hier die Verletzung des Styleguides?

Zitat:

Zitat von RavenIV
Aus diesem Grund

welchem Grund?
Zitat:

Zitat von RavenIV
würde Jemand, der MEINEN Styleguide (der auf dem Borland Styleguide basiert) in MEINER Abteilung permanent missachtet, erst eine Abmahnung und dann die Kündigung erhalten.

Schön. Aber was hat das mit meinem Code zu tun?

Gruß
xaromz

RavenIV 4. Okt 2007 10:13

Re: Funktion optimieren
 
Zitat:

Zitat von xaromz
gut, aber wo ist hier die Verletzung des Styleguides?

Nach jedem for..do oder if..then kommt ein Absatz und dann ein begin.

Zitat:

Zitat von xaromz
Zitat:

Zitat von RavenIV
Aus diesem Grund

welchem Grund?

Weil mir die Galle hochkommt.

alzaimar 4. Okt 2007 10:15

Re: Funktion optimieren
 
Zitat:

Zitat von RavenIV
Aus diesem Grund würde Jemand, der MEINEN Styleguide (der auf dem Borland Styleguide basiert) in MEINER Abteilung permanent missachtet, erst eine Abmahnung und dann die Kündigung erhalten.

Ja ja, nun beruhig dich mal. Wir sind nämlich nicht in DEINER Abteilung, sondern in der FREIEN Wildbahn und da machen wir, was wir wollen und guidestylen ( :wall: ) wie's uns gefällt. Ich finde den Borlandstyle nämlich zum :kotz:

Ich minimiere z.B. die Verwendung von Begin..End, arbeite dafür aber mit Leerzeilen. Ich mach das seit 20 Jahren so und mein Code ist ganz schön lesbar. Wem er nicht gefällt, schnappt sich einen Format-O-Maten und -wupps- hatta wassa will.

Im Übrigen ist das sowas von OT, das es fast schon lustig wird.

RavenIV 4. Okt 2007 10:20

Re: Funktion optimieren
 
Ja, schon gut.
Es geht schon wieder.

Soll doch jeder seinen Code schreiben wie es ihm beliebt.
Ich reg mich dann im Stillen darüber auf und schreibe vielleicht noch ne PN.

Ausserdem hab ich mit der StyleGuiderei nicht angefangen, es war Sidorion. :???:

alzaimar 4. Okt 2007 10:22

Re: Funktion optimieren
 
Zitat:

Zitat von RavenIV
Ja, schon gut.
Es geht schon wieder.

Soll doch jeder seinen Code schreiben wie es ihm beliebt.

:cheers:

RavenIV 4. Okt 2007 10:31

Re: Funktion optimieren
 
Zitat:

Zitat von alzaimar
Zitat:

Zitat von RavenIV
Ja, schon gut.
Es geht schon wieder.

Soll doch jeder seinen Code schreiben wie es ihm beliebt.

:cheers:

Aber nicht dass aus dem
:cheers:
ein :love: oder ein :kiss: oder gar ein :sharkylinchen: wird.
Das lassen wir doch lieber sein. :roll:

So genug offtopic.
Schnell wieder zurück zum eigentlichen Thema.

WS1976 4. Okt 2007 10:47

Re: Funktion optimieren
 
Hallo,

Object-Pascal ist doch ein so schön strukturierte Sprache. Ich versteh nicht wie man da so ein Durcheinander fabrizieren kann.
Auch ohne Styleguide gibts da eigentlich gar kein Problem.
Das einzige Problem das ich sehe sind die C'ler, die meinen mit Gewalt ihren Guidestyle durchzusetzen.

Grüsse
Rainer

peschai 4. Okt 2007 11:04

Re: Funktion optimieren
 
Hallo

Als reiner Delphianer:

Styleguides sind sehr wichtig und essentiell!

Es ist die einzige Überlebensstrategie um in Projkete die Wartbarkeit für die Zukunft zu sichern!
Desweiteren hängt die Qualität von Software sehr stark mit der "visuellen Qualität" von Sourcecode zusammen. Was passiert wenn Leute das Projekt verlassen und andere weiteremachen ? Wenn jeder seinen eigenen Stil einbringt, so daß andere nicht damit umgehen können so mag das für den Augenblick funktionieren aber nicht für die Zukunft.

alzaimar 4. Okt 2007 11:37

Re: Funktion optimieren
 
Gähn. DelForExp, JEDI-Code-Formatter, Gregs Formatter, etc. Wo ist euer Problem? Da einigt man sich auf irgendeine Einstellung und zieht die durch.

Sidorion 4. Okt 2007 14:03

Re: Funktion optimieren
 
Zitat:

Zitat von RavenIV
Ausserdem hab ich mit der StyleGuiderei nicht angefangen, es war Sidorion. :???:

Ich habe hier mit garnix angefangen, das war wenn schon, dann WS1976. Ich habe Alzimar im Ganzen Recht gegeben und lediglich auf die Gefahr hingewiesen, dass wenn eine einzelne Anweisung hinter einem Then folgt (also kein Begin..End Block) und man die Anweisung zeilenmäßig getrennt vom Then schreibt, irgendwer hergeht und zwischen das If und eben diese Anweisung eine Anweisung hinschreibt. Das führt dann dazu, dass der ganze Code in den Müll kann.
Deswegen kriegt in MEINER Abteilung jeder den Kopf abgerissen, der sowas macht (aber nicht von mir, sondern vom Chef :twisted: ). Aber wie gesagt: Es war nur ein Gefahrenhinweis, nicht aber eine Styleguidediskussion, weil wir eben in freier Wildbahn sind.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:39 Uhr.

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