Delphi-PRAXiS

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

klebe7 2. Okt 2008 18:04


Code optimieren
 
Hallo,

Ich bin Anfänger in Delphi und brauche mal Hilfe.
Könnt ihr mir Tipps geben, wie ich folgenden Code beschleunigen/optimieren kann, da er einfach zu langsam ist, wenn ich ihn oft aufrufe.

Delphi-Quellcode:
function RemoveChars(const ASource, AChars: string): string;
var
  i, j: Integer;
  bFlag: Boolean;
begin
  Result := '';
  for i := 1 to Length(ASource) do
  begin
    bFlag := False;
    for j := 1 to Length(AChars) do
      if ASource[i] = AChars[j] then
      begin
        bFlag := True;
        Break;
      end;
    if not bFlag then
      Result := Result + ASource[i];
  end;
end;

Klaus01 2. Okt 2008 18:14

Re: Code optimieren
 
Guten Abend,

vielleicht geht es so besser?

Delphi-Quellcode:
for i:=1 to length(AChars) do
  begin
    Source:= StringReplace(Source,AChars[i],'',rfReplaceAll);
  end;
Aber ich wüsste jetzt nicht wo in Deinem code eine Bremse
sein sollte.

Grüße
Klaus

DeddyH 2. Okt 2008 18:18

Re: Code optimieren
 
Mal aus der hohlen Hand:
Delphi-Quellcode:
type TChars = set of Char;

function RemoveChars(const aString: string; Chars: TChars): string;
var i, j: Integer;
begin
  SetLength(Result,Length(aString));
  j := 1;
  for i := 1 to Length(aString) do
    begin
      if not(aString[i] in Chars) then
        begin
          Result[j] := aString[i];
          Inc(j);
        end;
    end;
  SetLength(Result,Pred(j));
end;

alzaimar 2. Okt 2008 18:41

Re: Code optimieren
 
Hier eine Version, die nochmal 50% rausholt (die Zeit also quasi halbiert)
Delphi-Quellcode:
function PRemoveChars(const aString: string; Chars: TChars): string;
var
  pSource, pResult, pEnd: PChar;

begin
  SetLength(Result, Length(aString));
  pSource := @aString[1];
  pResult := @Result[1];
  pEnd := pSource + Length(aString) - 1;
  while pSource <= pEnd do begin
    if not (pSource^ in Chars) then begin
      pResult^ := pSource^;
      inc(pResult);
    end;
    inc(pSource);
  end;
  SetLength(Result, integer(pResult) - integer(@Result[1]));
end;

DeddyH 2. Okt 2008 18:43

Re: Code optimieren
 
Das dürfte aber Probleme geben, wenn man einen Leerstring übergibt.

klebe7 2. Okt 2008 18:45

Re: Code optimieren
 
Vielen Dank an alle. Ich probiere es aus.

alzaimar 2. Okt 2008 18:56

Re: Code optimieren
 
Zitat:

Zitat von DeddyH
Das dürfte aber Probleme geben, wenn man einen Leerstring übergibt.

Dann eben eine Abfrage einbauen, alter Pedant :zwinker:

DeddyH 3. Okt 2008 09:22

Re: Code optimieren
 
Mach ich mal:
Delphi-Quellcode:
function PRemoveChars(const aString: string; Chars: TChars): string;
var
  pSource, pResult, pEnd: PChar;

begin
  SetLength(Result, Length(aString));
  if Length(aString) > 0 then
    begin
      pSource := @aString[1];
      pResult := @Result[1];
      pEnd := pSource + Length(aString) - 1;
      while pSource <= pEnd do begin
        if not (pSource^ in Chars) then begin
          pResult^ := pSource^;
          inc(pResult);
        end;
        inc(pSource);
      end;
      SetLength(Result, integer(pResult) - integer(@Result[1]));
    end;
end;

Puhbaehr 5. Mär 2009 08:59

Re: Code optimieren
 
In meiner fast 10 jährigen Erfahrung mit Delphi bin ich eben das erste mal über eine Routine gestolpert die mir bisher unbekannt war.

Zitat:

Zitat von DeddyH
Mal aus der hohlen Hand:
Delphi-Quellcode:
type TChars = set of Char;

function RemoveChars(const aString: string; Chars: TChars): string;
var i, j: Integer;
begin
  //...
  SetLength(Result,Pred(j));
end;

Pred (x: Integer);
Ist die Routine Pred (x) so viel schneller als x - 1, dass sich die Verwendung lohnt?

Irgendwo hier im Forum las ich einmal, dass die Verwendung von inc/dec (x) sogar langsamer sei als x := x +/- 1;
Aus diesem Grund frage ich.

Gruß, Robert

Luckie 5. Mär 2009 09:03

Re: Code optimieren
 
Zitat:

Zitat von Puhbaehr
Irgendwo hier im Forum las ich einmal, dass die Verwendung von inc/dec (x) sogar langsamer sei als x := x +/- 1;
Aus diesem Grund frage ich.

Kann ich mir nicht vorstellen, da bei aktuellen Delphi Versionen identischer ASM Code generiert wird.

SirThornberry 5. Mär 2009 09:27

Re: Code optimieren
 
Ich würde pred an der Stelle zum Beispiel nur verwenden um mir eine zeile zu sparen. wobei ich mir das pred in dem genannten Beispiel sparen würde und lieber j mit 0 initialisieren und dafür das inc in der schleife eine Zeile weiter vor holen würde.(wenn es denn der Code sein sollte)
Delphi-Quellcode:
function RemoveChars(const aString: string; Chars: TChars): string;
var i, j: Integer;
begin
  SetLength(Result,Length(aString));
  j := 0;
  for i := 1 to Length(aString) do
  begin
    if not(aString[i] in Chars) then
    begin
      Inc(j);
      Result[j] := aString[i];
    end;
  end;
  SetLength(Result,j);
end;
Und je nach dem ob der Ausgangsstring überhaupt danach noch gebraucht wird würde ich das ganze zu einer Procedure wandeln und den Ausgangsstring ändern:
Delphi-Quellcode:
procedure RemoveChars(var aString: string; Chars: TChars);
var i, j: Integer;
begin
  j := 0;
  for i := 1 to Length(aString) do
  begin
    if not(aString[i] in Chars) then
    begin
      Inc(j);
      aString[j] := aString[i];
    end;
  end;
  SetLength(aString,j);
end;

DeddyH 5. Mär 2009 09:35

Re: Code optimieren
 
Wieso sparst Du da eine Zeile?
Delphi-Quellcode:
SetLength(Result,Pred(j));
oder
Delphi-Quellcode:
SetLength(Result,j-1);
macht ja keinen Unterschied. Ich kann auch nicht wirklich begründen, wieso ich im obigen Code Pred() verwendet habe, das mache ich nach Lust und Laune und nicht aus Gründen irgendwelcher Optimierungen.

SirThornberry 5. Mär 2009 09:37

Re: Code optimieren
 
das zeile sparen war darauf bezogen wenn man j danach noch verwenden will. Aber stimmt, in genanntem Beispiel wird es nicht mehr verwendet.

Puhbaehr 5. Mär 2009 10:29

Re: Code optimieren
 
Nu Lucky hat recht.

Code:
t := i - 1;

t := pred (i);

t := i;
t := t - 1;

t := i;
dec (t);
Delphi generiert für die vier Beispiele jeweils 100 % identischen ASM-Code:

Code:
004680D4 8BF3             mov esi,ebx
004680D6 4E              dec esi
Ich bin stehts auf der Suche nach Optimierungen hinsichtlich Geschwindigkeit sowie Lesbarkeit für das Schreiben zukünftiger Codes.

Nach dem Test sehe ich für mich keinen Grund meinen Stile durch die Verwendung von pred zu verändern. Meine Frage beantwortet in diesem Falle die deutlich höhere Lesbarkeit des ersten Beispiels.

Vielen Dank für das Feedback :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:01 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