Speed issues with filling a list view

  • Thread starter Thread starter Brian Henry
  • Start date Start date
B

Brian Henry

I was wondering how you guys would handle filling a list view with something
like 10,000 items which each have 10 sub items on them... there has to be
major speed issues with that right? Yet, applications like outlook and such
can retrieve and display tens of thousands of emails with virtually no
performance hit at all... how would we go about getting a .NET listview to
get similar performance? when I try to do what I said above, it takes about
15 seconds or more to fill it with that much information and that is just
random test data... not real life from a database data either
 
I do not think that it is a listview that is used; rather, I think that the
control is a datagrid. I also think that only that which is visible plus a
few more are actually loaded on initial load. The rest of the data is
loaded on demand to match the scrollbar. Counts, and pointers are the only
thing loaded on initial load.
 
The best performance I have gotten from a ListView is via
ListView.Items.AddRange(x)
where x is an array of ListViewItems. With the data volume you have,
I think the way to go is a worker thread that creates an array of
ListViewItems, loads data into the array, and from time to time calls
AddRange and reinitializes. Be aware of the need to execute AddRange on gui
thread rather than on the worker thread.
 
Brian Henry said:
I was wondering how you guys would handle filling a list view with
something like 10,000 items which each have 10 sub items on them... there
has to be major speed issues with that right? Yet, applications like
outlook and such can retrieve and display tens of thousands of emails with
virtually no performance hit at all... how would we go about getting a .NET
listview to get similar performance?

You may want to use a virtual listview:

<URL:http://www.ilypsys-systems.co.uk/ils1controls.zip>

Note that .NET 2.0's listview control will support a virtual mode
('VirtualMode' property) which allows to display millions of items
blindingly fast.
 
The best performance I have gotten from a ListView is via
ListView.Items.AddRange(x)
where x is an array of ListViewItems. With the data volume you have,
I think the way to go is a worker thread that creates an array of
ListViewItems, loads data into the array, and from time to time calls
AddRange and reinitializes. Be aware of the need to execute AddRange on gui
thread rather than on the worker thread.

I do agree that using AddRange is the fastest way. I will however
disagree about using a worker thread since the gain is minimal. In my
experience the majority of time will still be spent in the AddRange
method and not building the array.

Here is some modified sample code from one of my projects to use as a
base. Displaying 9600 items takes 1.5 seconds (which is acceptable for
me as a user of the program) on my Athlon XP 1700.

private void RefreshListView()
{
listView.BeginUpdate();
listView.Items.Clear();
AddItemsToListView();
listView.EndUpdate();
}

private void AddItemsToListView()
{
List<ListViewItem> items = new List<ListViewItem>();
foreach (Episode episode in filter.Execute(episodeList.Episodes))
items.Add(CreateListViewItem(episode));
listView.Items.AddRange(items.ToArray());
}

private static ListViewItem CreateListViewItem(Episode episode)
{
ListViewItem item = new ListViewItem(
new string[]
{
episode.OriginalAirdate.HasValue?
episode.OriginalAirdate.Value.ToShortDateString():"",
episode.Show.Name,
episode.Season.ToString(),
episode.EpisodeNumber.ToString(),
episode.Title
});
item.ForeColor = EpisodeForeColor(episode);
item.Tag = episode;
return item;
}

Even though I create lots of ListViewItems which contain a decent
amount of subitems(5). I still spend 90% of the time in the AddRange
method.
 
wow you are right, doing an addrange increased our performance by a lot of
time. Before it took 4530 milliseconds to fill, now it only takes 635
milliseconds
 
Back
Top