LeGEC
LeGEC

Reputation: 51850

TListView performance issues

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.SubItems.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 ?

Upvotes: 1

Views: 2940

Answers (4)

Ondrej Kelle
Ondrej Kelle

Reputation: 37211

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

Upvotes: 8

Im0rtality
Im0rtality

Reputation: 3533

@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

Upvotes: 0

Andrej Kirejeŭ
Andrej Kirejeŭ

Reputation: 5481

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

Upvotes: 4

SimaWB
SimaWB

Reputation: 9294

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

Upvotes: 4

Related Questions