var
  Frq:Int64;

procedure TForm1.FormCreate(Sender: TObject);
begin
  QueryPerformanceFrequency(Frq);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i,n,StrLen,Increasement:Integer;
  TempStr,Str:String;
  C1,C2,C3:Int64;
  CostTime,CostTime0,CostTime1,CostTime2:Single;
  Buf:TBuffer;
  LinkBuf:TLinkBuf;
begin
  StrLen:=SpinEdit1.Value;
  n:=SpinEdit2.Value;
  Increasement:=StrToInt(ComboBox1.Text)*1024;
  SetLength(TempStr,StrLen);
  FillChar(TempStr[1],StrLen,'A');
  Memo1.Lines.Add(#13#10'StrLen='+IntToStr(StrLen)+'   Count='+IntToStr(n)
    +'   Sum='+IntToStr(StrLen*n)+'   BufInc='+IntToStr(Increasement));

  //String
  Str:='';
  QueryPerformanceCounter(C1);
  for i:=n downto 1 do
    Str:=Str+TempStr;
  QueryPerformanceCounter(C2);
  CostTime:=(C2-C1)/Frq*1000;
  CostTime0:=CostTime;
  Memo1.Lines.Add(Format('String:     %.2fms',[CostTime]));

  //TBuffer
  Buf:=TBuffer.Create(0,Increasement);
  QueryPerformanceCounter(C1);
  for i:=n downto 1 do
    Buf.WriteBuf(@TempStr[1],StrLen);
  QueryPerformanceCounter(C2);
  Str:=Buf.AsString;
  QueryPerformanceCounter(C3);
  CostTime1:=(C2-C1)/Frq*1000;
  CostTime2:=(C3-C2)/Frq*1000;
  CostTime:=CostTime1+CostTime2;
  Memo1.Lines.Add(Format('TBuffer:    %.2f + %.2f = %.2fms',
    [CostTime1,CostTime2,CostTime]));
  Memo1.Lines.Add(Format('TBuffer/String=  %.2f',[CostTime/CostTime0]));

  if CheckBox1.Checked then
  begin
    //TBuffer_
    Buf.ClearBuf(false);
    QueryPerformanceCounter(C1);
    for i:=n downto 1 do
      Buf.WriteBuf(@TempStr[1],StrLen);
    QueryPerformanceCounter(C2);
    Str:=Buf.AsString;
    QueryPerformanceCounter(C3);
    CostTime1:=(C2-C1)/Frq*1000;
    CostTime2:=(C3-C2)/Frq*1000;
    CostTime:=CostTime1+CostTime2;
    Memo1.Lines.Add(Format('TBuffer_:   %.2f + %.2f = %.2fms',
      [CostTime1,CostTime2,CostTime]));
    Memo1.Lines.Add(Format('TBuffer_/String= %.2f',[CostTime/CostTime0]));
  end;
  Buf.Free;

  //TLinkBuf
  LinkBuf:=TLinkBuf.Create(Increasement);
  QueryPerformanceCounter(C1);
  for i:=n downto 1 do
    LinkBuf.AppendData(@TempStr[1],StrLen);
  QueryPerformanceCounter(C2);
  Str:=LinkBuf.AsString;
  QueryPerformanceCounter(C3);
  CostTime1:=(C2-C1)/Frq*1000;
  CostTime2:=(C3-C2)/Frq*1000;
  CostTime:=CostTime1+CostTime2;
  Memo1.Lines.Add(Format('TLinkBuf:   %.2f + %.2f = %.2fms',
    [CostTime1,CostTime2,CostTime]));
  Memo1.Lines.Add(Format('TLinkBuf/String=  %.2f',[CostTime/CostTime0]));

  if CheckBox1.Checked then
  begin
    //TLinkBuf_
    LinkBuf.ClearBuf(false);
    QueryPerformanceCounter(C1);
    for i:=n downto 1 do
      LinkBuf.AppendData(@TempStr[1],StrLen);
    QueryPerformanceCounter(C2);
    Str:=LinkBuf.AsString;
    QueryPerformanceCounter(C3);
    CostTime1:=(C2-C1)/Frq*1000;
    CostTime2:=(C3-C2)/Frq*1000;
    CostTime:=CostTime1+CostTime2;
    Memo1.Lines.Add(Format('TLinkBuf_:   %.2f + %.2f = %.2fms',
      [CostTime1,CostTime2,CostTime]));
    Memo1.Lines.Add(Format('TLinkBuf_/String= %.2f',[CostTime/CostTime0]));

    //Pure Move
    QueryPerformanceCounter(C1);
    SetLength(TempStr,Length(Str));
    QueryPerformanceCounter(C2);
    Move(Str[1],TempStr[1],Length(Str));
    QueryPerformanceCounter(C3);
    CostTime1:=(C2-C1)/Frq*1000;
    CostTime2:=(C3-C2)/Frq*1000;
    CostTime:=CostTime1+CostTime2;
    Memo1.Lines.Add(Format('Move:   %.2f + %.2f = %.2fms',
      [CostTime1,CostTime2,CostTime]));
    Memo1.Lines.Add(Format('Move/String= %.2f',[CostTime/CostTime0]));
  end;
  LinkBuf.Free;
end;