Why is my code so slow?

Sent from above (sorry) the answer is for those who do not have time to enter it, but may have similar problems.

Rule number 1, as always, moves as much as you can from cycles.
2, moving TField var: = ADODataSet.FieldByname () from loop 3, ADODataSet.DisableControls (); and ADODataSet.EnableControls (); around loop 4, stringGrid.Rows [r] .BeginUpdate () and EndUpdate () for each row (cannot perform whle control) each one shaved off for a few seconds, but I brought it to โ€œfaster than the eye can seeโ€, changing

loop
  stringGrid.RowCount := stringGrid.RowCount + 1;
end loop

before placement stringGrid.RowCount := ADODataSet.RecordCount;before the cycle

+1 and heartfelt thanks to everyone who helped.

(Now I will go and see what I can do to optimize TChart drawing, which is also slow ;-)


with approximately 3600 rows in the table, it takes 45 seconds to fill the grid of rows. What am I doing wrong?

   ADODataSet: = TADODataSet.Create (Nil);
   ADODataSet.Connection: = AdoConnection;

   ADODataSet.CommandText: = 'SELECT * FROM measurements';
   ADODataSet.CommandType: = cmdText;
   ADODataSet.Open ();

   while not ADODataSet.eof do
   begin
      TestRunDataStringGrid.RowCount: = TestRunDataStringGrid.RowCount + 1;

      measurementDateTime: = UnixToDateTime (ADODataSet.FieldByname ('time_stamp'). AsInteger);
      DoSQlCommandWithResultSet ('SELECT * FROM start_time_stamp', AdoConnection, resultSet);
      startDateTime: = UnixToDateTime (StrToInt64 (resultSet.Strings [0]));
      elapsedTime: = measurementDateTime - startDateTime;
      TestRunDataStringGrid.Cells[0, Pred(TestRunDataStringGrid.RowCount)] := FormatDateTime('hh:mm:ss', elapsedTime);
      TestRunDataStringGrid.Cells[1, Pred(TestRunDataStringGrid.RowCount)] := FloatToStrWithPrecision(ADODataSet.FieldByname('inputTemperature').AsFloat);
      TestRunDataStringGrid.Cells[2, Pred(TestRunDataStringGrid.RowCount)] := FloatToStrWithPrecision(ADODataSet.FieldByname('outputTemperature').AsFloat);
      TestRunDataStringGrid.Cells[3, Pred(TestRunDataStringGrid.RowCount)] := FloatToStrWithPrecision(ADODataSet.FieldByname('flowRate').AsFloat);
      TestRunDataStringGrid.Cells[4, Pred(TestRunDataStringGrid.RowCount)] := FloatToStrWithPrecision(ADODataSet.FieldByname('waterPressure').AsFloat * convert);
      TestRunDataStringGrid.Cells[5, Pred(TestRunDataStringGrid.RowCount)] := FloatToStrWithPrecision(ADODataSet.FieldByname('waterLevel').AsFloat);
      TestRunDataStringGrid.Cells[6, Pred(TestRunDataStringGrid.RowCount)] := FloatToStrWithPrecision(ADODataSet.FieldByname('cod').AsFloat);
      ADODataSet.Next;
   end;

   ADODataSet.Close();
   ADODataSet.Free();

:

Function  DoSQlCommandWithResultSet(const command : String; AdoConnection : TADOConnection; resultSet : TStringList): Boolean;
  var
        i : Integer;
        AdoQuery : TADOQuery;

begin
  Result := True;
  resultSet.Clear();

  AdoQuery := TADOQuery.Create(nil);
  try
    AdoQuery.Connection := AdoConnection;
    AdoQuery.SQL.Add(command);
    AdoQuery.Open();
    i := 0;
    while not  AdoQuery.eof do
    begin
      resultSet.Add(ADOQuery.Fields[i].Value);
      i := i + 1;
      AdoQuery.Next;
    end;

  finally
    AdoQuery.Close();
    AdoQuery.Free();
  end;
end;

+5
6

:

  • FieldByName . . . : InputTempField := ADODataSet.FieldByname('inputTemperature');
  • TestRunDataStringGrid.RowCount := TestRunDataStringGrid.RowCount + 1. , ADODataSet.RecordCount: TestRunDataStringGrid.RowCount := ADODataSet.RecordCount.
  • ADODataSet.DisableControls ADODataSet.EnableControls . , ADO, .
  • , " ". , ADO, , ADODataSet.CacheSize . , :)
+9
  • SELECT * FROM start_time_stamp 3,600 , , - . ?

  • SELECT , "*" WHERE, ( ).

  • "" , "*".

  • DoSQlCommandWithResultSet, , .

  • , . , , . ?

+10

ADODataSet.FieldByname('Fieldname') TField , ADODataset.FindField('Fieldname') . FindFieldByName .

Update:

procedure TForm1.Button1Click(Sender: TObject);
var
  InputTemp, OutputTemp: TField;
begin
  ADODataSet := TADODataSet.Create(Nil);
  try
    ADODataSet.Connection := ADOConnection;
    ADODataSet.CommandText := 'SELECT * FROM measurements';
    ADODataSet.Open;
    InputTemp := ADODataSet.FindField('inputTemperature');
    OutputTemp := ADODataSet.FindField('outputTemperature');
    // assign more fields here
    while not ADODataSet.Eof do begin
      // do something with the fields, for example:
      // GridCell := Format ('%3.2f', [InputTemp.AsFloat]);
      // GridCell := InputTemp.AsString;
      ADODataSet.Next;
    end;
  finally
    ADODataSet.Free;
  end;
end;

TADODataset ( TDataModule) .

+5
+2

, , TestRunDataStringGrid.BeginUpdate TestRunDataStringGrid.EndUpdate . ( , ).

AdoQuery.LockType := ltReadOnly , .

+2

You can also try the profiler tool instead of the sampler profiler to get better results (sampler samplers skip a lot of detailed information and in most cases they have less than 1000 samples per second and 1000 is already low: itโ€™s only useful to get a quick overview).

Tool Profilers:

+1
source

All Articles