« TDBGridの描画が変!?(MyBase接続時) | トップページ | MyBaseを試してみる。(CloneCursorでOnFilterRecord) »

MyBaseを試してみる。(AppendとInsert)

インデックスで順番を処理するなら AppendInsert も同じ使い方ができますよね。そこで、ふと疑問に思ったのですが、AppendInsert、この二つの処理はどちらが早いのでしょうか。

ClientDataSet1->DataSource1->DBGrid1と接続し、下記のプログラムで100, 300, 500, 1000, 3000, 5000, 10000, 30000, 50000レコードを AppendInsert を使って追加し、計測してみました。(基本的に3回ずつ)

// サンプルデータを追加します。
procedure MakeSample(CDS: TClientDataSet);
var
  No: Integer;
  F: Boolean;
begin
  F := CDS.Active;
  if not F then
    CDS.Open;
  try
    // サンプルデータの追加
    No := 0;
    with CDS do
    begin
      Inc(No);
      Appendrecord([No, 'iPod Touch','mobile']);
      Inc(No);
      Appendrecord([No, 'Zaurus C-860','mobile']);
      Inc(No);
      Appendrecord([No, 'Delphi 2009 Handbook','book']);
      Inc(No);
      Appendrecord([No, 'GEORGIA BLACK','Coffee']);
      CheckBrowseMode;
    end;
  finally
    if not F then
      CDS.Close;
  end;
end;

// データベースの作成
procedure CreateDB(CDS: TClientDataSet);
var
  I: Integer;
begin
  CDS.Close;
  CDS.FieldDefs.Add('ORD',ftInteger);
  CDS.FieldDefs.Add('ITEM',ftWideString,20);
  CDS.FieldDefs.Add('ITEM2',ftWideString,20);
  CDS.IndexDefs.Add('OrderNo','ORD', [ixPrimary]);
  CDS.CreateDataSet;
  CDS.Close;

  for I := 0 to CDS.FieldDefs.Count - 1 do
    CDS.FieldDefs[I].CreateField(CDS);

  // インデックスの設定
  CDS.IndexName := 'OrderNo';
  CDS.Open;
  MakeSample(CDS);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  CreateDB(ClientDataSet1);
end;

const
  K = 20000; // 回数
// Append
procedure TForm1.Button1Click(Sender: TObject);
var
  T: Cardinal;
  I: Integer;
begin
  T := GetTickCount;
  ClientDataset1.DisableControls;
  try
    for I := 0 to K-1 do
    begin
      ClientDataSet1.Append;
      ClientDataSet1.FieldByName('ITEM').AsString := 'Test';
      ClientDataSet1.FieldByName('ORD').AsInteger :=
        ClientDataSet1.RecordCount+1;
    end;
    ClientDataset1.CheckBrowseMode;
  finally
    ClientDataset1.EnableControls;
  end;
  Memo1.Lines.Add('Append:'+IntToStr(K)+
    FormatFloat(' #,##0 msec',GetTickCount-T));
end;

// Insert
procedure TForm1.Button2Click(Sender: TObject);
var
  T: Cardinal;
  I: Integer;
begin
  T := GetTickCount;
  ClientDataset1.DisableControls;
  try
    for I := 0 to K-1 do
    begin
      ClientDataSet1.Insert;
      ClientDataSet1.FieldByName('ITEM').AsString := 'Test';
      ClientDataSet1.FieldByName('ORD').AsInteger :=
        ClientDataSet1.RecordCount+1;
    end;
    ClientDataset1.CheckBrowseMode;
  finally
    ClientDataset1.EnableControls;
  end;
  Memo1.Lines.Add('Insert:'+IntToStr(K)+
    FormatFloat(' #,##0 msec',GetTickCount-T));
end;

[100回]
Append:100 0 msec
-------------------
Insert:100 0 msec

[300回]
Append:300 15 msec
Append:300 0 msec
Append:300 16 msec
-------------------
Insert:300 0 msec
Insert:300 16 msec
Insert:300 0 msec

[500回]
Append:500 16 msec
Append:500 15 msec
Append:500 16 msec
-------------------
Insert:500 0 msec
Insert:500 0 msec
Insert:500 0 msec

[1000回]
Append:1000 15 msec
Append:1000 15 msec
Append:1000 16 msec
-------------------
Insert:1000 15 msec
Insert:1000 15 msec
Insert:1000 16 msec

[3000回]
Append:3000 47 msec
Append:3000 46 msec
Append:3000 46 msec
-------------------
Insert:3000 31 msec
Insert:3000 31 msec
Insert:3000 31 msec

[5000回]
Append:5000 63 msec
Append:5000 62 msec
Append:5000 62 msec
-------------------
Insert:5000 47 msec
Insert:5000 47 msec
Insert:5000 47 msec

[10000回]
Append:10000 109 msec
Append:10000 109 msec
Append:10000 109 msec
---------------------
Insert:10000 109 msec
Insert:10000 109 msec
Insert:10000 110 msec

[20000回]
Append:20000 218 msec
Append:20000 218 msec
Append:20000 203 msec
---------------------
Insert:20000 265 msec
Insert:20000 281 msec
Insert:20000 281 msec

[30000回]
Append:30000 312 msec
Append:30000 312 msec
Append:30000 343 msec
---------------------
Insert:30000 499 msec
Insert:30000 484 msec
Insert:30000 483 msec

[50000回]
Append:50000 530 msec
Append:50000 546 msec
Append:50000 531 msec
-----------------------
Insert:50000 1,108 msec
Insert:50000 1,123 msec
Insert:50000 1,123 msec

[PC]
CPU: Intel Core i5-2400
Mem: 4GB
Delphi XE2 pro
※F9で実行させて、計測して終了させて、また実行させて計測して・・・(^-^) 

これらからおよそ10000回までの追加については、Insert、それ以上の場合には、Appendを使うといいかも知れません。テストのフィールドが単純なので、あくまでも参考データですけどね。

今回はGetTickCountで計測していますが、処理にかかった時間をより厳密に計算するには、timeGetTime を使います。

totonicaさんのサイト
Watercolor City
経過時間を計測する

|

« TDBGridの描画が変!?(MyBase接続時) | トップページ | MyBaseを試してみる。(CloneCursorでOnFilterRecord) »