开发者

TListView performance issues

开发者 https://www.devze.com 2023-01-11 15:55 出处:网络
I tried to use a TListView component to display rather large data lists (like 4000 rows large), and creating the list is incredibly slow - it takes something like 2-3 secs, which makes the UI all lagg

I tried to use a TListView component to display rather large data lists (like 4000 rows large), and creating the list is incredibly slow - it takes something like 2-3 secs, which makes the UI all laggy and close to unusable.

I fill the TListView.Items inside a BeginUpdate/EndUpdate block, with only preallocated strings - I mean : I build a list of all strings to store (which takes no humanly noticeable time), then I put them in the TListView.

I wish to display the TListView's content in vsReport mode with several columns.

The code looks like this :

MyList.Items.BeginUpdate;
for i := 0 to MyCount - 1 do
begin
  ListItem := MyList.Items.Add;
  ListItem.Caption := StrCaptions[i];
  ListItem.SubItems.Add(StrSubItems1[i]);
  ListItem.SubIt开发者_运维百科ems.Add(StrSubItems2[i]);
end;
MyList.Items.EndUpdate;

Is there some other hack I missed in the TListView component's logic ? or should I just forget about using this component for performances ?


You can use listview in virtual mode. Have a look at the virtuallistview.dpr demo.


You can try Virtual Treeview component. It says "Virtual Treeview is extremely fast. Adding one million nodes takes only 700 milliseconds"


Use separate structure for holding your data. Set OwnerData of TListView to True.


@4000 rows I get only ~700 ms (D2009) times. For more responsiveness you could separate to other thread or add dirty Application.ProcessMessages() into loop.

rows generated with this code in 16 ms:

  MyCount := 4000;

  dw := GetTickCount();
  for i := 0 to MyCount - 1 do begin
    StrCaptions.Add('caption'+IntToStr(i));
    StrSubItems1.Add('sub1'+IntToStr(i));
    StrSubItems2.Add('sub2'+IntToStr(i));
  end;
  ShowMessageFmt('%u ms', [GetTickCount() - dw]);

Printed with:

  MyList.Clear;

  dw := GetTickCount();
  MyList.Items.BeginUpdate;
  for i := 0 to MyCount - 1 do
  begin
    ListItem := MyList.Items.Add;
    ListItem.Caption := StrCaptions[i];
    ListItem.SubItems.Add(StrSubItems1[i]);
    ListItem.SubItems.Add(StrSubItems2[i]);
  end;
  MyList.Items.EndUpdate;
  ShowMessageFmt('%u ms', [GetTickCount() - dw]);

EDIT: I inserted Application.ProcessMessages() into print, but somewhy performance stays same

0

精彩评论

暂无评论...
验证码 换一张
取 消