The Embarcadero official said "TFDMemTable is faster than TClientDataSet",But I Make an little speed test and TFDMemtable slower than TClientDataset (Delphi XE7).

{Test 30k records            TClientDataSet TFDMemTableAppend         1482ms      2153msSaveToFile     125ms       348ms        SaveToStream   125ms       312msLoadFromFile   109ms       686msLoadFromStream 234ms       718ms }unit Unit1;interfaceuses  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error,  FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Comp.DataSet, FireDAC.Comp.Client, Data.DB,  Datasnap.DBClient, Vcl.StdCtrls, Vcl.Samples.Spin, FireDAC.Stan.StorageBin;type  TForm1 = class(TForm)    btnFDAppend: TButton;    btnAppend: TButton;    seCount: TSpinEdit;    btnFDEmptyDataSet: TButton;    btnEmptyDataSet: TButton;    lblClientDataset: TLabel;    lblFDMemTable: TLabel;    btnSaveToFile: TButton;    btnFDSaveToFile: TButton;    btnLoadFromFile: TButton;    btnFDLoadFromFile: TButton;    btnSaveToStream: TButton;    btnFDSaveToStream: TButton;    btnFDLoadFromStream: TButton;    btnLoadFromStream: TButton;    lblRecordCount: TLabel;    lblWhy: TLabel;    procedure FormCreate(Sender: TObject);    procedure btnFDAppendClick(Sender: TObject);    procedure btnAppendClick(Sender: TObject);    procedure btnFDEmptyDataSetClick(Sender: TObject);    procedure btnLoadFromFileClick(Sender: TObject);    procedure btnSaveToFileClick(Sender: TObject);    procedure btnFDSaveToFileClick(Sender: TObject);    procedure btnFDLoadFromFileClick(Sender: TObject);    procedure btnSaveToStreamClick(Sender: TObject);    procedure btnFDSaveToStreamClick(Sender: TObject);    procedure btnLoadFromStreamClick(Sender: TObject);    procedure btnFDLoadFromStreamClick(Sender: TObject);    procedure FormDestroy(Sender: TObject);    procedure btnEmptyDataSetClick(Sender: TObject);  private    FStartTime: DWORD;    FFDStream, FCDSStream: TMemoryStream;    FClientDataSet: TClientDataSet;    FFDMemTable: TFDMemTable;    function NewFDMemTable: TFDMemTable;    function NewClientDataSet: TClientDataSet;    procedure ShowDuration(Sender: TObject);  public    { Public declarations }  end;var  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btnFDAppendClick(Sender: TObject);var  I: Integer;begin  FStartTime := GetTickCount;  FFDMemTable.DisableControls;  try    for I := 1 to seCount.Value do    begin      FFDMemTable.Append;      FFDMemTable.FieldByName('ID').AsInteger := I;      FFDMemTable.FieldByName('Status').AsString := 'Code' + IntToStr(i);      FFDMemTable.FieldByName('Created').AsDateTime := Date();      FFDMemTable.FieldByName('Volume').AsFloat := Random(10000);      FFDMemTable.Post;    end;  finally    FFDMemTable.EnableControls;  end;  ShowDuration(Sender);end;procedure TForm1.btnLoadFromFileClick(Sender: TObject);begin  FStartTime := GetTickCount;  FClientDataSet.LoadFromFile('CDS.dat');  ShowDuration(Sender);end;procedure TForm1.btnSaveToFileClick(Sender: TObject);begin  FStartTime := GetTickCount;  FClientDataSet.SaveToFile('CDS.dat', dfBinary);  ShowDuration(Sender);end;procedure TForm1.btnFDEmptyDataSetClick(Sender: TObject);begin  FStartTime := GetTickCount;  FFDMemTable.EmptyDataSet;  ShowDuration(Sender);end;procedure TForm1.btnEmptyDataSetClick(Sender: TObject);begin  FStartTime := GetTickCount;  FClientDataSet.EmptyDataSet;  ShowDuration(Sender);end;procedure TForm1.btnFDSaveToFileClick(Sender: TObject);begin  FStartTime := GetTickCount;  FFDMemTable.SaveToFile('FD.dat', sfBinary);  ShowDuration(Sender);end;procedure TForm1.btnSaveToStreamClick(Sender: TObject);begin  FCDSStream.Clear;  FStartTime := GetTickCount;  FClientDataSet.SaveToStream(FCDSStream, dfBinary);  ShowDuration(Sender);end;procedure TForm1.btnFDLoadFromFileClick(Sender: TObject);begin  FStartTime := GetTickCount;  FFDMemTable.LoadFromFile('FD.dat', sfBinary);  ShowDuration(Sender);end;procedure TForm1.btnFDSaveToStreamClick(Sender: TObject);begin  FFDStream.Clear;  FStartTime := GetTickCount;  FFDMemTable.SaveToStream(FFDStream, sfBinary);  ShowDuration(Sender);end;procedure TForm1.btnFDLoadFromStreamClick(Sender: TObject);begin  FStartTime := GetTickCount;  FFDStream.Position := 0;  FFDMemTable.LoadFromStream(FFDStream, sfBinary);  ShowDuration(Sender);end;procedure TForm1.btnLoadFromStreamClick(Sender: TObject);begin  FStartTime := GetTickCount;  FCDSStream.Position := 0;  FClientDataSet.LoadFromStream(FCDSStream);  ShowDuration(Sender);end;procedure TForm1.btnAppendClick(Sender: TObject);var  I: Integer;begin  FStartTime := GetTickCount;  FClientDataSet.DisableControls;  try    for I := 1 to seCount.Value do    begin      FClientDataSet.Append;      FClientDataSet.FieldByName('ID').AsInteger := I;      FClientDataSet.FieldByName('Status').AsString := 'Code' + I.ToString;      FClientDataSet.FieldByName('Created').AsDateTime := Date();      FClientDataSet.FieldByName('Volume').AsFloat := Random(10000);      FClientDataSet.Post;    end;  finally    FClientDataSet.EnableControls;  end;  ShowDuration(Sender);end;procedure TForm1.FormCreate(Sender: TObject);begin  FFDMemTable := NewFDMemTable;  // FFDMemTable.FormatOptions.InlineDataSize := 10;  FClientDataSet := NewClientDataSet;  FCDSStream := TMemoryStream.Create;  FFDStream := TMemoryStream.Create;end;procedure TForm1.FormDestroy(Sender: TObject);begin  FreeAndNil(FFDMemTable);  FreeAndNil(FClientDataSet);  FreeAndNil(FCDSStream);  FreeAndNil(FFDStream);end;function TForm1.NewClientDataSet: TClientDataSet;begin  Result := TClientDataSet.Create(nil);  with Result do  begin    FieldDefs.Add('ID', ftInteger, 0, False);    FieldDefs.Add('Status', ftString, 10, False);    FieldDefs.Add('Created', ftDate, 0, False);    FieldDefs.Add('Volume', ftFloat, 0, False);    CreateDataSet;    LogChanges := False;  end;end;function TForm1.NewFDMemTable: TFDMemTable;begin  Result := TFDMemTable.Create(nil);  with Result do  begin    FieldDefs.Add('ID', ftInteger, 0, False);    FieldDefs.Add('Status', ftString, 10, False);    FieldDefs.Add('Created', ftDate, 0, False);    FieldDefs.Add('Volume', ftFloat, 0, False);    CreateDataSet;    LogChanges := False;  end;end;procedure TForm1.ShowDuration(Sender: TObject);var  s: string;  idx: Integer;begin  s := TButton(Sender).Caption;  idx := s.IndexOf('-');  if idx > 0 then    s := s.Substring(0, idx);  TButton(Sender).Caption := Format('%s-%dms', [s, (GetTickCount - FStartTime)]);end;end.

This is test result screenshot:

This is the test application source.

asked Nov 13 '14 at 6:32

    
Questions related to code must contain the code here, in the question itself. Having all of the relevant content somewhere else means that if that other site is unavailable for some reason, the question has no content or value for future readers. Questions asked here should be self-sufficient and not depend on another site for content. Please edit your question and include that content here. – Ken White Nov 13 '14 at 6:39
    
Try to replace your DisableControls..EnableControls block with BeginBatch..EndBatch. – TLama Nov 13 '14 at 9:27
    
Also initialize fields before the loop like fldID:= FClientDataSet.FindField('ID') and use fldID in the loop – Ravaut123 Nov 13 '14 at 10:10
2  
Thanks TLama, replace DisableControls..EnableControls block with BeginBatch..EndBatch 64bit TFDMemTable Append faster than TClientDataset. Thanks Ravaut123 Your suggestion is away of improve performance. – user3078904 Nov 13 '14 at 11:28