能增加ListView讀取速度嗎? |
答題得分者是:TATSU
|
HomeSound
中階會員 發表:44 回覆:178 積分:94 註冊:2002-08-31 發送簡訊給我 |
ListView->Items->BeginUpdate(); for(int i=1;i < RichEdit->Lines->Count;i ) { ListItem = ListView->Items->Add(); ListItem->Caption=tmp.sprintf("d",i); ListItem->SubItems->Add(tmp.sprintf("d",i)); RichEdit->SelStart=SendMessage(RichEdit->Handle,EM_LINEINDEX,i,0); RichEdit->SelLength=RichEdit->Lines->Strings[i].Length(); Section=RichEdit->SelText; ListItem->SubItems->Add(Section.SubString(38,25)); ListItem->SubItems->Add(Section.SubString(26,2)); ListItem->SubItems->Add(Section.SubString(21,4)); ListItem->SubItems->Add(Section.SubString(9,11)); ListItem->SubItems->Add(Section.SubString(1,8)); ListItem->SubItems->Add(Section.SubString(25,1)); ListItem->SubItems->Add(Section.SubString(29,8)); ListItem->SubItems->Add(Section.SubString(28,1)); ListItem->SubItems->Add(Section.SubString(64,58)); ListItem->SubItems->Add(Section.SubString(20,1)); } ListView->Items->EndUpdate();如上迴圈 再Win98上Run的話,加入2000行約兩秒鐘,但移到WinXP上Run要20秒左右 才能跑完,小弟程式是於Win98 BCB5.0上編譯的,不知為何會這樣
------
--==多看.多學.多聽==-- |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
這是之前討論過關於 TStringList 速度的問題
■ 讀取文字檔的速度 LoadFromFile()
http://delphi.ktop.com.tw/topic.php?topic_id=19925 關於您的問題,如果您已確定要加入多少行,可以先將 Capacity 的屬性設大,避免記憶體重配置的問題,看看可不可以提高速度。 沒空更新的網頁...
http://dllee.ktop.com.tw C及指標教學,計算機概論,資訊管理導論... http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell....
------
http://www.ViewMove.com |
HomeSound
中階會員 發表:44 回覆:178 積分:94 註冊:2002-08-31 發送簡訊給我 |
|
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
引言: 一樣也是慢在ADD()上,真不知道Win98跟WinXP的 ListView差在那兒 >>< face="Verdana, Arial, Helvetica"> 差在系統不一樣,因為 BCB/Delphi 也是叫用 Windows 系統提供的元件,只是幫我們包裝成 VCL 而已。 想要快的話,只能自己再加一些處理,例如不要全部都顯示,只顯示使用者看得到的部分等等,大部分慢都慢在記憶體重新配置以及顯示,避免不必要的記憶體重新配置及顯示,速度就能提升。 沒空更新的網頁... http://dllee.ktop.com.tw C及指標教學,計算機概論,資訊管理導論... http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell....
------
http://www.ViewMove.com |
TATSU
版主 發表:50 回覆:135 積分:62 註冊:2003-01-16 發送簡訊給我 |
如果你會 Delphi ,可以看看以下程式碼,我其實很少用 TreeView, ListView ,我最常用的是 Virtual TreeView ,因為實在快,至於你的問題,其實可以用到以下方法,不過我不會 C++,如果你會 Delphi ,應該明白這段程式做什麼。
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls; type PTxtLines = ^TTxtLines ; TTxtLines = Record Lines : String ; end; TForm1 = class(TForm) edtFilename: TEdit; btnGetFile: TButton; OpenDialog1: TOpenDialog; edtLines: TEdit; btnStandard: TButton; lblStandard: TLabel; lvStandard: TListView; lvVirtual: TListView; btnVirtual: TButton; lblVirtual: TLabel; procedure btnGetFileClick(Sender: TObject); procedure btnStandardClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure btnVirtualClick(Sender: TObject); procedure lvVirtualData(Sender: TObject; Item: TListItem); private { Private declarations } LineList : TList ; procedure ClearTxtLines ; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btnGetFileClick(Sender: TObject); begin if OpenDialog1.Execute then edtFilename.Text := OpenDialog1.FileName ; end; procedure TForm1.btnStandardClick(Sender: TObject); var nTotal, nLines : Integer ; cLine : String ; F1 : TextFile ; LineItem : TListItem ; tStart, tEnd : TDateTime ; begin if FileExists(edtFilename.Text) then begin tStart := Now ; nTotal := StrToInt(edtLines.Text) ; nLines := 0 ; AssignFile(F1, edtFileName.Text) ; Reset(F1) ; lvStandard.Items.BeginUpdate ; lvStandard.items.clear ; while Not(Eof(F1)) do begin inc(nLines) ; ReadLn(F1, cLine) ; LineItem := lvStandard.Items.Add ; LineItem.Caption := cLine ; if nLines = nTotal then break ; end; lvStandard.Items.EndUpdate ; CloseFile(F1) ; tEnd := Now ; lblStandard.Caption := FormatDateTime('hh:mm:ss.zzz', tEnd - tStart) ; end; end; procedure TForm1.FormCreate(Sender: TObject); begin LineList := TList.Create ; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin ClearTxtLines ; LineList.Free ; end; procedure TForm1.btnVirtualClick(Sender: TObject); var nTotal, nLines : Integer ; cLine : String ; F1 : TextFile ; LineItem : TListItem ; tStart, tEnd : TDateTime ; aRecord : PTxtLines ; begin if FileExists(edtFilename.Text) then begin tStart := Now ; nTotal := StrToInt(edtLines.Text) ; nLines := 0 ; AssignFile(F1, edtFilename.Text) ; Reset(F1) ; ClearTxtLines ; while Not(Eof(F1)) do begin inc(nLines) ; ReadLn(F1, cLine) ; New(aRecord) ; aRecord.Lines := cLine ; LineList.Add(aRecord) ; if nLines = nTotal then break ; end; CloseFile(F1) ; tEnd := Now ; lvVirtual.Items.Count := nTotal ; //<== 讓 ListView 知道有多少筆資料 lvVirtual.Invalidate ; lblVirtual.Caption := FormatDateTime('hh:mm:ss.zzz', tEnd - tStart) ; end; end; procedure TForm1.lvVirtualData(Sender: TObject; Item: TListItem); begin if Item.Index < LineList.Count then begin // 因應這個 Item 的 Index 由已讀取資料的 list 內抓取字串 Item.Caption := PTxtLines(LineList.Items[Item.Index]).Lines ; end; end; procedure TForm1.ClearTxtLines ; var i : integer ; begin if LineList.Count > 0 then begin for i := 0 to (LineList.Count - 1) do Dispose(PTxtLines(LineList.Items[i])) ; end; LineList.Clear ; end; end.執行這一支程式時,我找了 mysql.txt ,一個十分大的檔案,載入 20,000 行,使用基本 ListView 就要用 30 秒,但用上 ownerdata ,將每一行的文字都存到 TList 內一個自訂的資料類型內,就只需要用 0.161 秒,它只是花時間去讀檔案,沒有實質的資料加到 Listview 去儲存,要找資料時,你便要提供一筆資料給它。你如果當中沒有什麼花俏的東東,你可以用上這個方法,多大的文字檔也可以十分快的速度秀出。 20,000 行:30.013, 0.161 秒 50,000 行:3:46.285, 0.351 秒 因為你的一篇舊文章,我再翻看 ListBox 一些資料,兩者基本上都可以用到這個方法,只差是用那一種方法去讀取文字檔及儲存類型,但一定不是放到 Listview 或 Listbox 的內部儲存。 Listbox.style := lbVirtual ; Listbox.count := xx // no. of lines ListBox.OnData event ListView.OwnerData := True ; ListView.Items.Count := xx //no. of lines ListView.OnData event 兩者速度一致,都可以用這個方法,至於用 TList 或 TStringList 做儲存,就由你發揮。 哈哈...不會 C 的人,走到這裏回答問題... 發表人 - |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
感謝 TATSU 版主,
原來 ListBox 還可以這樣用... 我立刻試一下,但發現 BCB5 沒有此 style,也許 BCB6 應該有提供。
而 ListView 則有此功能 (我好像還沒用過它 < >),以後可能要多用用看囉 < > P.S. 我也不懂 Delphi 但有時也會到 Delphi 去走走,互相交流一下吧 <>沒空更新的網頁...
href="http://dllee.adsldns.org">http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell.... 發表人 - dllee 於 2004/04/14 08:09:21
------
http://www.ViewMove.com |
TATSU
版主 發表:50 回覆:135 積分:62 註冊:2003-01-16 發送簡訊給我 |
引言: 感謝 TATSU 版主, 原來 ListBox 還可以這樣用... 我立刻試一下,但發現 BCB5 沒有此 style,也許 BCB6 應該有提供。 而 ListView 則有此功能 (我好像還沒用過它 < >),以後可能要多用用看囉 < > P.S. 我也不懂 Delphi 但有時也會到 Delphi 去走走,互相交流一下吧 <>沒空更新的網頁... href="http://dllee.adsldns.org">http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell.... 發表人 - dllee 於 2004/04/14 08:09:21因為不懂 C ,只可以提供一個原理,希望可以幫到你們解決問題。 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |