Einzelnen Beitrag anzeigen

jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#9

Re: Stringkonkatenation ist schneller als direktes Kopieren?

  Alt 19. Mär 2008, 20:25
Lass das ganze doch mal unter Delphi 1, 2, 3, 4, 5, 6, 7 und 2005 laufen. Dann wirst schon sehen, warum die das so gemacht haben. Tipp: Ab Delphi 2006 wird der FastMM4 als Standard Speichermanager eingesetzt.


Der FastMM ist fast nicht zu schlagen. Aber ein paar mickrige Millisekunden habe ich dann doch noch herausschlagen können. Die lassen sich aber nicht mittels GetTickCount ermitteln.

Delphi-Quellcode:
Function V2(s: TStringList): Integer;
Var
  l, i, j, n: Integer;
  z: PChar;
  x: String;
  Arr: array of record
    Data: PChar;
    Len: Integer;
  end;
Begin
  n := 0;
  SetLength(Arr, s.Count);
  For i := 0 To s.count - 1 Do
  begin
    Arr[i].Data := PChar(s[i]); // nur einmal in s.Get(i) wird LStrAsg ausgeführt => 3x LOCK
    Arr[i].Len := Length(PString(@Arr[i].Data)^);
    inc(n, Arr[i].Len);
  end;

  SetLength(x, n);
  j := 0; // PChar startet bei 0
  For i := 0 To High(Arr) Do Begin
    z := Arr[i].Data;
    l := Arr[i].Len;
    Move(z^, PChar(PChar(Pointer(x)) + j)^, l * SizeOf(Char)); // kein UniqueString aufrufen
    inc(j, l);
  End;
 Result := Length (x);
End;

procedure TForm1.btClick(Sender: TObject);
Var
  s: TStringList;
  i : IntegeR;
  t0 : Cardinal;
  z0: Int64;
  z1: Int64;
  Freq: Int64;
begin
  QueryPerformanceFrequency(Freq);
  s := TStringlist.Create;
  try
    for i:=1 to 1000000 do s.add(IntToStr(i));

    QueryPerformanceCounter(z0);
    v1(s);
    QueryPerformanceCounter(z1);
    Memo.Lines.Add('Stringkonkatenation: '+FloatToStr((z1 - z0) / Freq));

    QueryPerformanceCounter(z0);
    v2(s);
    QueryPerformanceCounter(z1);
    Memo.Lines.Add('Direktes Einkopieren: '+FloatToStr((z1 - z0) / Freq));
  finally
    s.free;
  end;
end;
Stringkonkatenation: 0,07990568633723
Direktes Einkopieren: 0,072708333042328
  Mit Zitat antworten Zitat