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.