Thema: Delphi Funktion optimieren

Einzelnen Beitrag anzeigen

Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Funktion optimieren

  Alt 31. Aug 2005, 15:32
So ich hab auch noch bischen rumprobiert

AppendStringIfUnique = 422 ms
AddTok = 578 ms
AddIt2(von mir) 219 ms
AddIt3(von mir) 266 ms

[Edit]
Fehler in Funktion wurde behoben und Zeiten korrigiert
AddIt2 entfernt überflüssige Trennzeischen nicht
AddIt3 entfernt überflüssige Trennzeischen
[/Edit]
Allerdings weiß ich nicht ganz ob unter irgendwelchen Umständen meine Funktion fehlerhaft zurückgibt, wäre also nicht schlecht wenn mal jemand bischen testen könnte.
Delphi-Quellcode:
function AddIt2(const S, T: string; const C: Char; CS: Boolean = False): String;
  function IsSame(Str1: PChar; Str2: PChar; ALen: Integer): Boolean;
  var LPos: Integer;
  begin
    result := True;
    LPos := 0;
    while result and (LPos < ALen) do
    begin
      if Str1^ <> Str2^ then
        result := False;
      inc(Str1);
      inc(Str2);
      inc(LPos);
    end;
  end;
var LPos1, LPos2, LSourceLen, LTLen: Integer;
    LFound: Boolean;
    LS, LT: String;
    LSP, LTP: PString;
begin
  LSourceLen := Length(S);
  if Length(S) = 0 then
    result := T
  else begin
    if CS then
    begin
      LSP := @S;
      LTP := @T;
    end else begin
      LS := AnsiLowerCase(S);
      LT := AnsiLowerCase(T);
      LSP := @LS;
      LTP := @LT;
    end;
    LFound := False;
    LTLen := Length(T);
    LPos1 := 1;
    LPos2 := 1;
    while (LPos2 <= LSourceLen) and not(LFound) do
    begin
      if (LSP^[LPos2] = C) then
      begin
        LFound := (LPos2 - LPos1 = LTLen) and IsSame(@LSP^[LPos1], PChar(LTP^), LPos2 - LPos1);
        LPos1 := LPos2 + 1;
      end else if (LPos2 = LSourceLen) then
      begin
        LFound := (LPos2 - LPos1 + 1 = LTLen) and IsSame(@LSP^[LPos1], PChar(LTP^), LPos2 - LPos1 + 1);
        LPos1 := LPos2 + 1;
      end;
      inc(LPos2);
    end;

    if LFound then
      result := S
    else
    begin
      if S[LSourceLen] = C then
        result := S + T
      else
        result := S + C + T;
    end;
  end;
end;
Delphi-Quellcode:
function AddIt3(const S, T: string; const C: Char; CS: Boolean = False): String;
  function IsSame(Str1: PChar; Str2: PChar; ALen: Integer): Boolean;
  var LPos: Integer;
  begin
    result := True;
    LPos := 0;
    while result and (LPos < ALen) do
    begin
      if Str1^ <> Str2^ then
        result := False;
      inc(Str1);
      inc(Str2);
      inc(LPos);
    end;
  end;
var LPos1, LPos2, LSourceLen, LTLen: Integer;
    LFound: Boolean;
    LS, LT: String;
    LSP, LTP: PString;
begin
  LSourceLen := Length(S);
  if LSourceLen = 0 then
    result := T
  else begin
    if CS then
    begin
      LSP := @S;
      LTP := @T;
    end else begin
      LS := AnsiLowerCase(S);
      LT := AnsiLowerCase(T);
      LSP := @LS;
      LTP := @LT;
    end;
    LFound := False;
    LTLen := Length(T);
    LPos1 := 1;
    LPos2 := 1;
    while (LPos2 <= LSourceLen) and not(LFound) do
    begin
      if (LSP^[LPos2] = C) then
      begin
        LFound := (LPos2 - LPos1 = LTLen) and IsSame(@LSP^[LPos1], PChar(LTP^), LPos2 - LPos1);
        LPos1 := LPos2 + 1;
      end else if (LPos2 = LSourceLen) then
      begin
        LFound := (LPos2 - LPos1 + 1 = LTLen) and IsSame(@LSP^[LPos1], PChar(LTP^), LPos2 - LPos1 + 1);
        LPos1 := LPos2 + 1;
      end;
      inc(LPos2);
    end;

    if LFound then
      result := S
    else
    begin
      if S[LSourceLen] = C then
        result := S + T
      else
        result := S + C + T;
    end;

    //überflissige Zeischen rauskicken
    LPos2 := 1;
    LSourceLen := Length(result);
    for LPos1 := 1 to LSourceLen do
    begin
      if (result[LPos1] <> C) or (LPos1 <= 1) or (result[LPos1 - 1] <> C) then
      begin
        result[LPos2] := result[LPos1];
        inc(LPos2);
      end;
    end;
    if result[LPos2 - 1] = C then
      dec(LPos2);
    SetLength(result, LPos2 - 1);
  end;
end;
@Dani: Die Funktion ist um den Faktor 10 Schneller? Ich kann mir nicht vorstellen das So große unterschiede auftreten das deine Funktion gleich 10 mal schneller ist. Außerdem hast du bei dieser Variante das Casesensitive vergessen. Wenn ich bei mir als Parameter das Casesensitive auf False setze komme ich dann auch nur noch auf 78 ms

@Pseudemys Nelsoni: Bist du dir sicher das du die Trennzeischen herausfiltern willst wenn ein Leerstring dazwischen ist? Schließlich ist ein Leerstring nicht unbedingt etwas ungültiges.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat