我有一个包含10列的TStringGrid.添加500行需要大约2秒钟.这是正常的表现吗?
对我来说似乎有点慢.
我从数据库查询中获取数据.如果我遍历查询但不将结果写入StringGrid,则该过程大约需要100毫秒,因此数据库不会减慢速度.
添加行后,StringGrid性能很好.
这是我正在使用的代码
Grid.RowCount := Query.RecordCount;
J := 0;
while not Query.EOF do
begin
Grid.Cells[0,J]:=Query.FieldByName('Value1').AsString;
Grid.Cells[1,J]:=Query.FieldByName('Value2').AsString;
Grid.Cells[2,J]:=Query.FieldByName('Value3').AsString;
// etc for other columns.
Inc(J);
Query.Next();
end;
Run Code Online (Sandbox Code Playgroud)
实际代码实际上有点复杂(表列与查询列不完全对应),但这是基本的想法
我发现在执行大量记录时非常重要的另一件事是为每个字段使用适当的TField变量.FieldByName每次迭代Fields集合,因此不是最高性能的选项.在循环之前定义每个字段,如:
var
f1, f2: TStringField;
f3: TIntegerField;
begin
// MyStringGrid.BeginUpdate; // Can't do this
// Could try something like this instead:
// MyStringGrid.Perform(WM_SETREDRAW, 0, 0);
try
while ... do
begin
rowvalues[0] := f1.AsString;
rowvalues[1] := f2.AsString;
rowvalues[2] := Format('%4.2d', f3.AsInteger);
// etc
end;
finally
// MyStringGrid.EndUpdate; // Can't - see above
// MyStringGrid.Perform(WM_SETREDRAW, 1, 0);
// MyStringGrid.Invalidate;
end;
end;
Run Code Online (Sandbox Code Playgroud)
这与BeginUpdate/Endupdate一起并在适当时调用Query.DisableControls.
解决方案是使用"行"属性一次性添加所有值.
我的代码现在看起来像这样:
Grid.RowCount := Query.RecordCount;
rowValues:=TStringList.Create;
J := 0;
while not Query.EOF do
begin
rowValues[0]:=Query.FieldByName('Value1').AsString;
rowValues[1]:=Query.FieldByName('Value2').AsString;
rowValues[2]:=Query.FieldByName('Value3').AsString;
// etc for other columns.
Grid.Rows[J]:=rowValues;
Inc(J);
Query.Next();
end;
rowValues.Free; // for the OCD among us
Run Code Online (Sandbox Code Playgroud)
这使得时间从2秒减少到大约50毫秒.