![]() |
Diese Funktion schneller machen?
ok, diese funktion ist nur ein beispiel, aber viele meiner andere laufen genauso ab...
Delphi-Quellcode:
ziel dieser funktion ist es einen string "ordentlich" zu machen, anhand des seperators.... also wenn ich z.b so einen string übergebe:
function fmtstr(const s: string; const c: char): string;
var i: integer; b: boolean; begin result := ''; b := false; for i := 1 to length(s) do begin if s[i] = c then begin if (result = '') or (b = true) then continue; b := true; end else b := false; result := result + s[i]; end; if (result <> '') and (result[length(result)] = c) then setstring(result, pchar(result), length(result)-1); end; Zitat:
Zitat:
wenn ich diese funktion 1million mal in einer schleife aufrufe dauert das ganze ca 1,094 sekunden.... gibt es irgendwie eine schnellere methode für diese funktion? es sollten keine funktionen aus der VCL verwendet werden. |
Re: Diese Funktion schneller machen?
Zitat:
Und dieses Prozedere wird nun 1 Mio mal ausgeführt. Besser du setzt Result vor der Schleife auf die Worst-Case Länge (in deinem Fall SetLength(Result, Length(S))). Nun kannst du die Zeichen direkt zuweisen "Inc(RealLen);Result[RealLen] := S[i];". Nach dem Schleifendurchlauf setzt du nun mit SetLength(Result, RealLen) die entgültige Länge fest. Zitat:
Für was brauchst du denn b. Das wird doch gar nicht ausgewertet. |
Re: Diese Funktion schneller machen?
hallo jbg,
danke für deine antwort, ich werde versuchen es umzusetzen. b ist true wenn das letzte zeichen der seperator war, so vermeide ich das ein seperator doppelt geschrieben wird. EDIT:
Delphi-Quellcode:
was ist denn hier falsch?
function fmtstr(const s: string; const c: char): string;
var i, len: integer; b: boolean; begin Result := ''; if s <> '' then begin setlength(result, length(s)); len := 0; b := false; for i := 1 to length(s) do begin if s[i] = c then begin if (result[1] = #0) or (b = true) then continue; b := true; end else b := false; len := len + 1; result[len] := s[i]; end; if result[length(result)] = c then setlength(result, len-1) else setlength(result, len); end; end; wenn ich das tue: Zitat:
wieso ist der punkt am ende noch da? |
Re: Diese Funktion schneller machen?
Zitat:
Zitat:
|
Re: Diese Funktion schneller machen?
moin jbg,
habe es nun so:
Delphi-Quellcode:
funktioniet einwandfrei, danke nochmal.
function fmtstr(const s: string; const c: char): string;
var i, len: integer; b: boolean; begin if s <> '' then begin len := 0; b := false; setlength(result, length(s)); result[1] := #0; for i := 1 to length(s) do begin if s[i] = c then begin if (result[1] = #0) or (b) then begin b := true; continue; end; b := true; end else b := false; len := len + 1; result[len] := s[i]; end; if result[len] = c then setlength(result, len-1) else setlength(result, len); end; end; was meinst du mit "tödlich" enden? generell meine boolesche variable dort oder das ich "= true" benutzt habe? btw: kann ich das doppelte "b := true" irgendwie zu einem machen? |
Re: Diese Funktion schneller machen?
Ich wuerde das letzte Zeichen am Ende einmal pruefen und gegebenenfalls weghauen.
Damit verschwindet dieser unsinnige und unelegante Test mit der booleschen Variablen. |
Re: Diese Funktion schneller machen?
brauche die variable aber für die mittleren seperatoren, wenn B true ist, dann war das zeichen davor bereits der seperator
|
Re: Diese Funktion schneller machen?
Moin!
Ich frage mich ob es nicht schneller sein würde, mit Pos ein doppelten Separator zu suchen und wenn man was findet einfach ab da mit der Schleife weiter zu laufen und zu sehen wieviele Separatoren noch kommen. Wenn man in der Schleife einen nicht Separator findet, dann kannst du mit Delete() doch bei der Position von Pos()+1 bis zur aktuellen Stelle die Zeichen löschen und gut. Sollte das nicht schneller gehen als auch noch die Strings in der grossen Schleife durchzugehen. Und mit Pos() klappt es auch, da ein .. nachher nicht mehr zu finden sein sollte. Nur mal so als Idee... MfG Muetze1 |
Re: Diese Funktion schneller machen?
Zitat:
1. Ist ein Funktionsaufruf immer "Verhältnismäßig" langsam. 2. geht Pos immer von Anfang den String durch. Macht also viele unnütze Aktionen. 3. Bei Delete ist doch das gleiche Probleme wie viele SetLengths. Es wird jedes mal neuer Speicher angefordert und alter freigegeben. Was insgesamt sicherlich negativ auf die Performance ausschlagen wird. Einzige Optimierung die mir noch einfallen würde ist, am Anfang alle Separatoren zu überspringen.
Delphi-Quellcode:
(irgendwie sowas) Dadurch spart man sich das result[1] = #0 im if.
var
Start: Integer; begin Len:=Length(s); Start:=1; while (result[Start]=c) and (Start<Len) do inc(Start); for i := Start to length(s) do Statt Len := Len+1 benutze inc(Len); statt immer s[i] und result[len] zu machen könntest du auch einen Pointer (PChar) verwenden, der immer erhöht wird.[/delphi] |
Re: Diese Funktion schneller machen?
Wie waere es denn mit
Result := StringReplace(S, Ch + Ch, Ch, [rfReplaceAll]); Dann muss nur noch auf ein Ch am Ende getestet werden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:09 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