In my previous blog on BulkObservableCollection vs ObservableCollection, I showed you means to improve the performance of adding huge data to UI controls. Now if you were evaluating various third party UI control libraries then apart from control features they offer, you might be interested in evaluating how fast these controls can render whlie handling large data sets. As the precise evaluation methodology might vary from vendor to vender, I would tell you generic means to evaluate UI performance / rendering speed, so that we could do apples-to-apples comparision across UI control libraries of your choice.
Let’s consider a scenario where you have DataGrid’s ItemsSource property is set to a collection. When this collection gets populated or changed, the DataGrid control renders UI for the corresponding data. As you all might know, “The only thread that’s allowed to directly access a property value of controls is the primary UI thread” [1]. Because of this, anything and everything that DataGrid control need to do for creating the UI should happen on the UI Thread. We take as an advantage to time the UI rendering as shown below.
// When user clicks LoadData button, below method triggers in. // _personsData is already preloaded, so we just add data to collection protected void OnLoadDataCommand(object obj) { CurrentMetric = new PerformanceMetric { DataGridType = GridViewModel.DataGridType, StartedAt = DateTime.Now, RowCount = _personsData.Count }; if (GridViewModel.Data.Count > 0) GridViewModel.Data.Clear(); GridViewModel.Data.AddRange(_personsData); } // The UI grids subscribe to CollectionChanged event and update // the grid accordingly. So we hookup our own handler to it public DataGridPerformanceViewModel() { // some code here GridViewModel.Data.CollectionChanged += DataOnCollectionChanged; } // In this OnCollectionChanged event handler we would like to // compute rendering time by running below code into UI thread // this ensures that computation code executes after rendering UI private void DataOnCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (GridViewModel.Data.Count > 0) Application.Current.RootVisual.Dispatcher .BeginInvoke(() => { CurrentMetric.CompletedAt = DateTime.Now; CurrentMetric.CalculateDuration(); PerformanceMetrics.Add(CurrentMetric); InvokeRenderCompleted(new PerformMetricEventArgs(CurrentMetric)); }); }
The difference in the rendering speed could be in the order of milli seconds. I am by no means endorsing one vendor is performing better than the other. The results could vary from machine to machine and vendor library version to version. So feel free to download the source from here and plugin 3rd party vendor libraries of your choice and evaluate it for yourself or run the demo page from here. I would post my performance metrics soon.
References:
[1] – ‘Updating the UI from a Secondary Thread‘ by Ted Pattison