Is Locating a Clientdataset very expensive?

Asked

Viewed 1,390 times

2

Make a locate of a dataset connected to the bank, certainly is quite costly. But make a locate in a dataset with in-memory data only, is a good practice? Or would it be better to create a array?

Grateful.

  • Have you considered the possibility of using a TDictionary ?

  • @Victorzanella No, you can give more details about the operation of TDictionary?

  • just to confirm, which version of Delphi you are using ?

  • @Victorzanella Delphi XE7

2 answers

2


Here is a simple example of using the Dictionary.

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  System.Generics.Collections, Vcl.StdCtrls;

type

  TPessoa = class
    id: integer;
    nome: string;
    sobrenome: string;
    idade: integer;
    sexo: string;
  end;

  TListaPessoa = TObjectList<TPessoa>;

  TForm2 = class(TForm)
    btnBuscarPessoa: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btnBuscarPessoaClick(Sender: TObject);

  private
    FListaPessoa: TListaPessoa;
    FDicionarioPessoa: TDictionary<integer, TPessoa>;

    procedure AdicionarPessoas;
    procedure AlimentarDicionario;

  end;

var
  Form2: TForm2;

implementation

uses
  StrUtils;

{$R *.dfm}




procedure TForm2.AdicionarPessoas;
var
  i: integer;
begin

  for i := 1 to 10000 do
  begin

    FListaPessoa.Add(TPessoa.Create);
    FListaPessoa.Last.id        := i;
    FListaPessoa.Last.nome      := 'Nome' + IntToStr(Random(1000));
    FListaPessoa.Last.sobrenome := 'Sobrenome' + IntToStr(Random(1000));
    FListaPessoa.Last.idade     := Random(80);
    FListaPessoa.Last.sexo      := IfThen(odd(FListaPessoa.Last.id + FListaPessoa.Last.idade), 'M', 'F');

  end;

end;



procedure TForm2.AlimentarDicionario;
var
  FPessoa: TPessoa;
begin
  for FPessoa in FListaPessoa do
    if (not(FDicionarioPessoa.ContainsKey(FPessoa.id))) then
      FDicionarioPessoa.Add(FPessoa.id, FPessoa);
end;



procedure TForm2.FormCreate(
  Sender:
  TObject);
begin
  FListaPessoa      := TListaPessoa.Create;
  FDicionarioPessoa := TDictionary<integer, TPessoa>.Create;

  AdicionarPessoas;
  AlimentarDicionario;

end;



procedure TForm2.btnBuscarPessoaClick(Sender: TObject);
var
  identificador: integer;
begin

  identificador := Random(10000);

  ShowMessage(
    'A pessoca com o id ' + IntToStr(identificador) + ' é ' + FDicionarioPessoa.Items[identificador].nome + ' ' + FDicionarioPessoa.Items[identificador].sobrenome +
    ' tem ' + IntToStr(FDicionarioPessoa.Items[identificador].idade) + ' anos de idade e é do sexo ' +
    IfThen(FDicionarioPessoa.Items[identificador].sexo = 'M', 'masculino', 'feminino')

    );

end;

end.

Note that the legal methods of the Dictionary are the ContainsKey or ContainsValue.

Note: In the test I did, I put 7000000 records, and the search is instant.

Note 2:Data ordering is also fast with data dictionary.

  • Thank you very much and congratulations for the example, very detailed and practical! @Victor Zanella

  • Aaah, I forgot to tell you, but the classes could be interfaces. In this case I forgot to release the created objects.

1


It is more expensive in processing. Mainly because with each new execution of locate, you would have to position the record at the beginning of Dataset.

A better option would be to use Findkey([]).

To use it, you only need to configure and use an index in Dataset and use the fields in Findkey.

Ex:

cdsDataSet.IndexDefs.add('IDX_NOME','CAMPO1;CAMPO2;CAMPO3',[]);
cdsDataSet.IndexName := 'IDX_NOME';

// Observe que você não precisa passar todos os campos do índice
// Mas precisa seguir sempre a mesma ordem.

if cdsDataSet.FindKey([_valorCampo1, _valorCampo2]) then
  showMessage('Achei')
else
  ShowMessage('não achei');

Browser other questions tagged

You are not signed in. Login or sign up in order to post.