πŸ“œ ⬆️ ⬇️

Delphi: the fastest DataSet (TJvMemoryData, TMemTableEh, TdxMemData, TkbmMemTable)

In this article, I will conduct a comparative analysis of DataSet'ov, which keep the data in memory.

List of DataSets


  1. TJvMemoryData
    Developer: JEDI Visual Component Library (JCL + JVCL) Community
    JCL (version 2.8)
    JVCL (version 3.50)
    β†’ Official website
  2. TMemTableEh
    Developer: EhLib
    Version: 9.0.040
    β†’ Official website
  3. TdxMemData
    Developer: DevExpress
    Version: 15.2.2
    β†’ Official website
  4. TkbmMemTable
    Developers: Components4Developers
    Version: 7.74.00 Professional Edition
    β†’ Official website

DataSet comparison options


  1. Insert records
  2. Sort records

Environment

Delphi10.2 Tokyo Starter
operating systemWindows 7 SP1 Ultimate x64
CPUIntel Core i5
Ram8 GB

Test data


DataSets will be tested on data obtained from the Firebird database. For comparative analysis, I created 100,000 records in the database with different data types:

β€’ whole numbers;
β€’ real numbers;
β€’ dates;
β€’ lines;
β€’ Images.

Comparison


  1. Data loading
    DatasetLoadFromDataSetManualThe average
    TJvMemoryData7.7846 sec5,7500 seconds6.7673 sec
    TMemTableEh4,5114 sec7.2978 sec5.9046 sec
    TdxMemData6.3804 sec6.5082 sec6.4443 sec
    TkbmMemTable5.4474 sec6.0562 sec5.7518 sec
    The loads for each DataSet were performed 5 times, the arithmetic average was calculated from the obtained values. The average value is the arithmetic average of the load values ​​using the LoadFromDataSet method and the manual load value.
    ')
    Results:

    TMemTableEh - the fastest data load using the LoadFromDataSet method
    TJvMemoryData - the fastest manual data download
    TkbmMemTable - the fastest average data load

    Time measurement source code
    var start_time, end_time, total_time: double; start_time := GetTickCount; ... end_time := GetTickCount; total_time := (end_time - start_time) / 1000; 

    Load data source code LoadFromDataSet
     //TJvMemoryData //function LoadFromDataSet(Source: TDataSet; RecordCount: Integer; Mode: TLoadMode; DisableAllControls: Boolean = True): Integer; JvMemoryData.LoadFromDataSet(FIBDataSet, -1, lmCopy); //TMemTableEh //function LoadFromDataSet(Source: TDataSet; RecordCount: Integer; Mode: TLoadMode; UseCachedUpdates: Boolean): Integer; MemTableEh.LoadFromDataSet(FIBDataSet, -1, lmCopy, true); //TdxMemData //procedure LoadFromDataSet(DataSet : TDataSet); dxMemData.LoadFromDataSet(FIBDataSet); //TkbmMemTable //procedure TkbmCustomMemTable.LoadFromDataSet(Source:TDataSet; CopyOptions:TkbmMemTableCopyTableOptions; Mapping:string=''); kbmMemTable.LoadFromDataSet(FIBDataSet, [mtcpoAppend]); 

    Manual source code
     while not FIBDataSet.Eof do begin table.Append; table.FieldByName('ID').AsInteger := FIBDataSet.FieldByName('ID').AsInteger; table.FieldByName('SUMM').AsFloat := FIBDataSet.FieldByName('SUMM').AsFloat; table.FieldByName('COMMENT').AsString := FIBDataSet.FieldByName('COMMENT').AsString; ... table.Post; FIBDataSet.Next; end; table.First; 

    TJvMemoryData is the only DataSet whose manual loading of data turned out to be faster than loading using the LoadFromDataSet method.

    TdxMemData is the only DataSet that, after loading data using the LoadFromDataSet method, does not return a position in the DataSet to the first record.
  2. Sorting
    DatasetIntegerReal numberLineThe average
    TJvMemoryData0.3492 sec0.8330 sec1,9938 sec1,0587 sec
    TMemTableEh0.9014 sec0.8642 sec3.6876 sec1.8177 sec
    TdxMemData0,3616 s0.3650 sec0.9134 sec0.5467 sec
    TkbmMemTable0.1996 sec0.2186 sec0.7550 sec0.3897 sec
    Sorting for each DataSet'a was performed 5 times, the arithmetic average was calculated from the obtained values. The average value is the arithmetic average of the sort values.

    Results:

    TkbmMemTable - the fastest sorting of integers
    TkbmMemTable - the fastest sorting of real numbers
    TkbmMemTable - the fastest sorting of lines
    TkbmMemTable - the fastest average sorting

    Time measurement source code
     var start_time, end_time, total_time: double; start_time := GetTickCount; ... end_time := GetTickCount; total_time := (end_time - start_time) / 1000; 

    Source code for sorting data
     //TJvMemoryData //procedure SortOnFields(const FieldNames: string = ''; CaseInsensitive: Boolean = True; Descending: Boolean = False); JvMemoryData.SortOnFields(fields, false, false); //TMemTableEh //procedure SortByFields(const SortByStr: string); MemTableEh.SortByFields(fields); //TdxMemData dxMemData.SortedField := fields; //TkbmMemTable //procedure SortOn(const FieldNames:string; Options:TkbmMemTableCompareOptions); kbmMemTable.SortOn(fields, []); 


I note that only for the TMemTableEh DataSet when sorting by several fields you can set a different sorting direction for each field (ascending / descending).

Conclusion


The undisputed leader was the DataSet TkbmMemTable , but all the other DataSets showed good results. But you can use TkbmMemTable only with Delphi XE2.

Of course, it is unlikely that you need to load 100,000 records on real data for display to the user. Also, when choosing a DataSet, it is necessary to take into account that on a different data set (for example, in the absence of downloading images or for an x64 application), the results of the speed of work may be different. In addition, many DataSets have additional functionality for working with a grid from their library.

More about TMemTableEh


The TMemTableEh component appeared in EhLib 4.0. All library components, including TMemTableEh, have been running since Delphi 7.

The advantages of using MemTableEh compared to other DataSets are the following:

  1. It supports a special interface that allows the DBGridEh component to view all data without moving the active record.
  2. Allows you to upload data from a TDataDriverEh object (DataDriver property).
  3. Allows you to upload changes back to DataDriver, promptly or deferred (depending on the properties of CachedUpdates).
  4. Allows you to create a master / client relationship on the client (by filtering records) or on an external source (by updating the [Params] parameters and re-querying the details with DetailDataDriver).
  5. Allows you to sort data, including Calculated and Lookup fields.
  6. Allows you to create and fill in data in design-time and save the data in a dfm-file form.
  7. Allows you to store records in the form of a tree. Each record can have node / branch records and itself be a node of another parent record. The TDBGridEh component supports the display functionality of the tree structure of these records.
  8. Allows you to connect to the internal array of another TMemTableEh component (ExternalMemData property) and work with its data: sort, filter, edit.
  9. It has an interface for getting a list of all column values, ignoring the local DataSet filter. TDBGridEh uses this property to automatically generate a list in the dropdown dropdown filter.

About TRxMemoryData


Development: RxLib
The TRxMemoryData component appeared in version RxLib 2.60.

The DataSet TRxMemoryData does not participate in the comparison, because in 2002 the RxLib library was officially incorporated into the JVCL. JVCL has a utility for quickly replacing all Rx components, functions and units on the JVCL version.

Why go to JVCL:

Unlike RxLib, JVCL is evolving. Errors are corrected. Regularly released version with support for new versions of Delphi. JVCL components support newer versions of Windows and Windows styles.

How do I use DataSets in my practice?


  1. TRxMemoryData
  2. TMemTableEh
  3. TRxMemoryData
  4. TJvMemoryData
  5. TkbmMemTable

Source: https://habr.com/ru/post/357716/


All Articles