I need to display lots of rows in a grid added at a pretty high frequency (up to 10 rows per second in some cases) I chose ListView because I assume is the fastest grid control in WPF. (certainly a lot faster than GridView)
CPU utilization gets pretty high after couple hundred thousand items were added and they continue to come in. This is rather surprising, as ListView renders only the visible rows, so it should not matter how many are added in total.
My first approach was binding it to ObservableCollection but after a while, the CPU utilization goes up, and the whole Window get jittery.
Than i tried binding it to a regular List, which appears to be faster, however i do need to call the .Refresh() on the list often, which after a while slams the CPU as well.
Than i attempted subclassing ObservableCollection to chunk inserts hoping that batching them would improve performance/decrease cpu workload, but this approach appears to require calling CollectionView.Refresh which is the same as calling Reset() on the collection, and also ineficient when there are lots of items in the collection.
Clearing the observablecollection and than calling myListView.Items.Refresh() to bring it back down to 0 brings cpu usage back to the starting point.
Starting to run out of ideas here.. Again, my aim here, is to add/display lots of items and display 8 column grid, in the most performant manner.. ListView seems good, there just have to be some ways i could further tweak it..
UPDATE
after profiling, ObservableCollection 800k rows in the grid, the most cpu intensive work is done by :
although depending on session those numbers vary greatly..
UPDATE 2 .. ok BindingList appears to be the clear winner here.
here are results (in ticks) side by side with 1 million rows each (and adding 10 items per second):
ObservableCollection: http://i.imgur.com/7ZoSv.png
BindingList http://i.imgur.com/jm5qF.png
you can see overall drop in CPU activity, and about half the ticks required to process the tree in Binding List case! My thanks to Akash for this great idea.
Instead of using ObservableCollection I will suggest BindingList class, you can do something like this..
BindingList<string> list = new BindingList<string>();
list.AllowEdit = true;
list.AllowNew = true;
list.AllowRemove = true;
// set the list as items source
itemCollection.ItemsSource = list;
// add many items...
// disable UI updation
list.RaiseListChangedEvents = false;
for each(string s in MyCollection){
list.Add(s);
}
// after all.. update the UI with following
list.RaiseListChangedEvents = true;
list.ResetBindings(); // this forces update of entire list
You can enable/disable updating even in batches, instead of adding everything at one shot, BindingList has been functioning better then ObservableCollection in all my UI, I wonder why everywhere people talk more about ObservableCollection when BindingList really superseds ObservableCollection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With