Improving the WPF DataGrid performance

14 July 2009

Over the past six months, the DXGrid team has been making progress improving our WPF data grid in two orthogonal directions. First they've been adding extra functionality you can read about here; things like printing support (including printing to PDF, HTML, XLS(X), etc, etc), editors, data validation, new item row, and so on, and second, they've been improving its performance.

Don't get me wrong, the performance was great to begin with. We've always gone after performance when scrolling, filtering, sorting, grouping and the like, and, like our other data grids for WinForms, ASP.NET and Silverlight, we've certainly concentrated on processing large data sources quickly using server mode. But there was one scenario we weren't happy with: the initial load time. That is, the time taken from starting to display a form containing a grid to the point where it's usable.

I thought it would be instructive to anyone creating a WPF application to discuss what we found and what we decided to do about it. The conclusions we reached have already affected (and will affect) our other controls and you may learn something from this investigation yourselves in your own work.

The team did a couple of spikes with profiler in hand. (Yes, it does bear pointing out explicitly: you can't decide anything about performance or know where such issues exist unless you use a profiler. There are a couple of very good ones on the market, so go buy one now if you're interested in improving performance.) The spikes gave us these two issues:

  • we had a large visual element tree for each row and cell
  • we had a large number of data bindings happening for each cell

The first was more due to our desire to have a very flexible and theme-able data grid, where you, the developer/designer, could manipulate appearance and effects down to the smallest detail using XAML. Once the visual tree was created (which took time), it would be reused for any further manipulations with the grid and was very fast since everything was already present. The conclusion was we should reduce the size of the visual tree to improve the initial load time.

Here's some statistics. Between the v2009.1 beta (which is all anyone has at the moment) and the v2009.2 release (coming soon), the number of visual tree elements for a text cell has been reduced from 11 to 4, and the number of visual elements for a row (excluding the cells), down from 38 to 32 (and we're dithering about removing another couple). What does that mean in terms of time? Well for a grid showing 30 active rows with 12 columns, the team have halved the initial load time. For 5 columns, it's about 2/3 of the original time.

The benefits of these optimization efforts are three-fold: first, of course, the initial load is much faster. Second, the changes also improve the speed of operations like resizing or moving columns (the visual tree needs fixing up in those scenarios too), or of expanding/collapsing groups (again, the visual tree needs fixing). In these scenarios, the time taken to fix up the visual tree was originally hidden to a certain extent by the fetching of data.

Third, despite the reduction in visual elements, we've still managed to maintain the flexibility of the tree with regard to applying themes. We felt that the ability to theme our grid was of extreme importance to the designers and developers using our WPF data grid: they should be able to easily change the appearance using XAML because, well, that's what you do with WPF. We did consider removing more visual elements and instead hard-coding the visual appearance (some work was done on this to prove it could have improved performance further), but we strongly believe that in so doing we'd have tossed out the appearance customization baby with the visual element bathwater. So, we stopped where we did because we thought that we had the right tension between flexibility and performance.

The second performance issue above was due to some inefficient programming, more than anything else. So, in order to improve things, all we had to do was improve the code that bound data, or make sure it only happened once.

So, in conclusion, when you are writing your WPF application, pay special attention to your visual tree. Just because creating a single visual element is fast, don't forget that it takes time to create a lot of them and it's all too easy to overload your visual element tree using the designer. So make sure that your own initial load times are kept in check.

7 comment(s)
Tim Shnaider

Julian, could you please recommend/name the profilers you refer too.

14 July, 2009
Roman

AQtime from AutomatedQA

www.automatedqa.com/.../aqtime

15 July, 2009
Steve Sharkey

Surely DXProfiler would sit nicely next to Refactor & Coderush?

15 July, 2009
J.C.M. Bijleveld

Can we expect the same performance improvement in the Silverlight DataGrid in v2009.2?

Also we would like to know the release date for v2009.2.

15 July, 2009
Brendon Muck [DevExpress MVP]

I'll give my 2 cents on the rest of this article after I look up what "orthogonal" means.

15 July, 2009
Ray Navasarkian (DevExpress)

Brendon, when you find out, make sure to let me know as well :-)

15 July, 2009
Kai Fjellstadsveen

>Third, despite the reduction in visual elements, we've still >managed to maintain the flexibility of the tree with regard to >applying themes.

This is really good news Julian. Until now I've been using the standard WPF ListView. The listview is fine for simple list, but it's a very slow in grouping and it a lot of work to implement sorting and filtering - even though I'm using MVVM. Looking forward to the release!

Have a great day and may the source be with you.

21 August, 2009

Please login or register to post comments.