繼上個帖子的問題,繼續研究下,希望大神能解答
https://bbs.csdn.net/topics/392406195
對比了一下ListView 和 DBGrid直接寫入資料速度(3000條資料,每條資料60個欄位)
DBGrid: Append,FieldByName 寫入用時2秒多
ListView:SubItems.Add 寫入用時4秒多
光這么看貌似DBGrid略勝一籌
但是,ListView有一個OwnerData屬性,開啟后使用OnData方法重繪資料的時間只有0.02秒
所以問題來了,DBGrid是否也有ListView這種機制,不在螢屏中的資料不刷出來,向下滾動的時候才刷出來
如果有的話要如何實作,最好能貼一下簡易的代碼,當然了別用類似Page Down這種按一下下一頁這種方式,需要和ListView一樣一個頁面顯示,滾動條下來自然的刷出來
uj5u.com熱心網友回復:
可能有人會說,既然ListView控制元件重繪效率這么高,我還干嘛閑著蛋疼想把ListView換成DBGrid而且控制元件一換,這個界面中于此控制元件相關代碼全部都要重寫,費時費勁
主要原因有2個,
1,,DBGrid控制元件可以給欄位增加資料型別ListView不行,而實際運用中需要更具資料型別來決定左對齊右對齊,或者別的效果,ListView只能每一個欄位手動來調整,太麻煩,目前已經有60多個欄位了,保不齊后面隨著需求的增加欄位持續變多,維護起來太累
2,排序。現在在OnData重繪資料之前,先要對一個Tlist資料用Sort進行一次排序,極大的耗費時間,高峰時界面可能直接卡死(此界面資料實時性要求非常高,如果監控3000個客戶,實時主推重繪,峰值可能每秒成百上千次重繪頻率),而DBGrid是通過添加索引欄位來排序,效率要快很多。
uj5u.com熱心網友回復:
是不是我這情況可以 ClientDataSet 設定 packetRecords?但是我packetRecords輸入了一個條目數,還是沒啥用,不知道要怎么使用
uj5u.com熱心網友回復:
FetchOnDemand 設定成True了,packetRecords 設定了50,但還是全刷uj5u.com熱心網友回復:
上次的帖子不是已經解決了DBGrid的性能問題了嗎?當時是3000行3列的資料,只用了0.012秒,今天我測驗了一下,就算是60列,也只用了0.25秒,難道你的電腦或網路很慢?uj5u.com熱心網友回復:
如果你用的帶Firedac的Delphi,用TFDMemTable代替TClientDataSet, 60列3000行資料只需0.12秒就完成了uj5u.com熱心網友回復:
之前主要是沒有測驗多欄位情況,兩三個欄位是很快,但是這次測驗了60個欄位一下就卡起來了,莫非是我代碼沒寫好,還有就是目前我用delphi6 沒有TFDMemTable
procedure TForm1.Button1Click(Sender: TObject);
var
BeginTime: TDateTime;
iLoop,jLoop: Integer;
begin
BeginTime := Now;
with ClientDataSet1 do
begin
DisableControls; //切斷 ClientDataSet 和控制元件的關聯
for iLoop := 0 to 3000 do
begin
Append;
for jLoop := 1 to 60 do
begin
FieldByName('Field'+IntToStr(jLoop)).AsString := 'Code' + intToStr(iLoop);
end;
end;
Post;
First;
EnableControls; //恢復 ClientDataSet 和控制元件的關聯
end;
Edit1.Text := FormatDateTime('hh:nn:ss.zzz', Now-BeginTime);
BeginTime := Now;
ListView1.Items.Count := 3000;
Edit3.Text := FormatDateTime('hh:nn:ss.zzz', Now-BeginTime);
end;
uj5u.com熱心網友回復:
另外還是想問一下,DBGrid有木有類似于ListView中OnData的實作方式,畢竟幾遍你這邊測驗的 60列,0.25秒和OnData0.02 也有著十幾倍速度的差距
uj5u.com熱心網友回復:
可能是Delphi版本太老了, 不能用新版本?uj5u.com熱心網友回復:
版本的確沒辦法升級,畢竟公司大家統一的開發環境,不是隨便就能換的
TFDMemTable不能使用其實問題也不是很大了,0.25秒種方式其實也能接受
但不知道代碼要怎么實作,麻煩大神提供下代碼來看看,我的代碼上買貼出來了,就是要2秒左右
uj5u.com熱心網友回復:
就是類似于上面你提供的代碼uj5u.com熱心網友回復:

type
TForm1 = class(TForm)
Button1: TButton;
DataSource1: TDataSource;
Edit1: TEdit;
耗時: TLabel;
DBGrid1: TDBGridEh;
ClientDataSet1: TClientDataSet;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
I: Integer;
S: String;
begin
with ClientDataSet1.FieldDefs do
begin
for I := 1 to 20 do
begin
S := IntToStr(I);
Add('Code' + S, ftString, 8 );
Add('Name' + S, ftString, 20);
Add('Number'+ S, ftInteger );
end;
end;
DataSource1.DataSet := ClientDataSet1;
DBGrid1.DataSource := DataSource1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
BeginTime: TDateTime;
I, J: Integer;
S: String;
begin
BeginTime := Now;
with ClientDataSet1 do
begin
DisableControls;
Close;
CreateDataSet;
Open;
LogChanges := False;
for I := 1 to 3000 do
begin
Append;
for J := 1 to 20 do
begin
S := IntToStr(J);
FieldByName('Code'+ S).AsString := 'Code' + intToStr(I);
FieldByName('Name'+ S).AsString := 'Name' + intToStr(I);
FieldByName('Number'+ S).AsInteger := I;
end;
Post;
end;
EnableControls;
end;
Edit1.Text := FormatDateTime('hh:nn:ss.zzz', Now-BeginTime);
end;
uj5u.com熱心網友回復:
你好像少了下面幾句:Close;
CreateDataSet;
Open;
LogChanges := False;
另外,post放的位置也不對
uj5u.com熱心網友回復:
我是界面初始化的時候已經做了CreateDataSet
點擊按鈕只是插入資料,所以就沒有那幾句
然后post放在外面感覺可以少提交幾次,理論應該還會快一點
uj5u.com熱心網友回復:
測驗了一下和這些代碼沒啥關系,把你代碼完完全全復制黏貼過來,還是2秒,見鬼了機器性能應該不至于,去年的蘋果電腦裝虛擬機的,記憶體分配了8個G,硬碟是固態的,跑跑這種簡單程式應該不會有性能問題才對
嚴重懷疑是delphi版本問題
uj5u.com熱心網友回復:
估計是虛擬機的緣故了,你把程式方式copy到非虛擬機上運行一下就知道是不是了。uj5u.com熱心網友回復:
試過了,不是虛擬機問題,換了臺戴爾電腦,8G記憶體,固態硬碟,運行結果比我電腦還要糟糕,2.5秒uj5u.com熱心網友回復:
那你自己找一臺電腦,裝一下新版本的delphi(例如Delphi 11.2),試試編譯運行一下, 看看是不是版本的問題。uj5u.com熱心網友回復:
如果單純是顯示和重繪問題,select top n * from TABLE也可以解決,就是太麻煩了uj5u.com熱心網友回復:
我們不是直接訪問資料庫的,前臺用功能號的形式訪問后臺so,so訪問資料庫,打包好資料回傳給前臺
所以DBGrid控制元件也只能手動插入資料Append,FieldByName,Post 這樣操作
uj5u.com熱心網友回復:
感覺上使用DBGrid比較好,它能與資料集相關聯,而ListView功能 上不及DBGrid。uj5u.com熱心網友回復:
安裝EhLib,用其中的TMemTableEh代替delphi自帶的TClientDataSet試試uj5u.com熱心網友回復:
DBGrid的資料顯示方式,跟ListView的自畫方式(OwnerDraw)是類似的。因為DBGrid只是展示它下面關聯的資料集的資料,而資料本身就已經存在了,不像ListView普通情況下要執行AddItems的操作形成展示資料,所以DBGrid的在展示資料上速度更快。而如果采用ListView的OwnerDraw,其欲展示的資料,普通做法是預先生成在記憶體中,在展示資料時也只是展示可見部分,不可見的行列不會去讀取和處理的,所以速度也會很快。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/37803.html
標籤:VCL組件開發及應用
上一篇:請大神幫忙編輯一個彩票程式
