Pergunta

I am using Delphi 2007 and the TcxGrid to show the contents of a file library. The database houses information about the type of file, name, path, and extension.

In testing I am loading 1700 records into the grid through the TDataSet. I also make room in the grid for 3 more fields which need yet to be calculated. They are if the files exists, size of the file, and date modified.

My goal is to show the user all of the information that's stored (which works great and is fast) then in a background thread find the information for the other three fields of data and then insert them into the TcxGrid. This question has little if nothing to do with the threading I am doing. Its working fine.

My problem is that accessing the fields in the grid that is already constructed has a huge slowdown when I access it. I have tried two different ways ...

  1. Grid.DataController.Values[RecordIndex,FieldIndex] - but this is a variant and I suspect that is why it is so slow

  2. Grid.DataController.DataSet.FindFirst Grid.DataController.DataSet.FindNext Grid.DataController.DataSet.Fields[FieldIndex] But using this "seek" method is just as slow as the first method I tried. Locate and moveby are slow as well.

So long question short, What is the fastest way to access a record?

Foi útil?

Solução 3

The updating code needed to be within a begin/end update was my big problem.

Thank you Lieven for your comment as it was the solution to my problem. And thank you Gad and Daniel for responses which I learned from.

This would have been more apparent to everyone had I more time yesterday to post some code.

Outras dicas

Please also mention whether you are using a TcxGridDBTableView or TcxGridTableView?

I think using non-db aware TcxGridTableView or TcxBandedGridTableView with

View.DataController.Values[RecordIndex, FieldIndex] is the fastest.

Even if you have a db application you can load the non-db version of the view on the initialization and than handle DataController events to detect data changes and issues the respective SQL commands for updating the database.

You can fill the view like this:

class procedure TForm1.FillView(const View: TcxGridBandedTableView; const Sql: string);
var
  Reader: TMyOrmDataReader;
  i: Integer;
begin
  Assert(Assigned(View), 'View is not assigned parameter.');
  with View.DataController do
  begin
    BeginFullUpdate;
    try
      Reader := TMyOrm.GetDataReader(SQL);
      try
        i := 0;
        RecordCount := 50 * 1000; // make it something big in order to avoid constant resizing by 1
        while Reader.Read do
        begin
          // Fill the view
         Values[i,  0] := Reader.GetInt32(0);
         Values[i,  1] := Reader.GetString(1);
         Inc(i);
        end;
        RecordCount := i - 1;
      finally
        Reader.Free;
      end;
    finally
      EndFullUpdate;
    end;
  end;
end;

And then access values like:

View1.DataController.Values[View1.DataController.FocusedRecordIndex, View1Column1.Index].AsString

You could work with table/dataset first appending the missing data and then show all the fields as datbound.

I know this is an old thread, but I'll mention that switching the grid to using Provider mode is another way to improve loading speed, because it essentially turns the grid loading into a virtual operation. (Records aren't loaded until they're needed for display or other data access.) After that, the DataController caches them, so access is very fast once loaded.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top