DCSIMG
WPF Performance Sweets – ContentControl (Part 2) - Essential WPF

WPF Performance Sweets – ContentControl (Part 2)

Part 1

Yesterday I went back to my customer, tried to figure out if the whole concept of using data as the content of a ContentControl instead of holding a logical tree, is truly contribute to the whole system, and guess what? It is not!

Well it figured out that setting the content property with non-visual element only postponed the tree-traversal. We figured this out by trying to measure the total elapsed time between setting the content property to null and up until the view completely disappeared.

To measure this we called the Dispatcher.BeginInvoke method with Background priority. Note that I used different set of controls to put more pressure and to turn the Dispatcher.BeginInvoke invocation time negligible.

The results showed us that the direct technique is a little bit faster in total time, but much slower when setting the content property (in our case the total time is more important).

 

private void Button_Click(object sender, RoutedEventArgs e)

        {

            if (_placeholder.Content != null)

            {

                Stopwatch stopWatch = Stopwatch.StartNew();

                _placeholder.Content = null;

 

                long setContentTime = stopWatch.ElapsedMilliseconds;

                Dispatcher.BeginInvoke(

                    DispatcherPriority.Background, (Action)delegate

                {

                    stopWatch.Stop();

                    long unloadViewInclusiveTime = stopWatch.ElapsedMilliseconds;

                    long unloadViewExclusiveTime = unloadViewInclusiveTime - setContentTime;

                    LogTime(setContentTime, unloadViewInclusiveTime, unloadViewExclusiveTime);

                });

            }

        }

 

        private static void LogTime(

            long setContentTime,

            long unloadViewInclusiveTime,

            long unloadViewExclusiveTime)

        {

            Debug.WriteLine(string.Format(

                "Time to set ContentControl.Content property: {0}ms.", setContentTime));

            Debug.WriteLine(string.Format(

                "Exclusive Time to unload view: {0}ms.", unloadViewExclusiveTime));

            Debug.WriteLine(string.Format(

                "Inclusive Time to unload view: {0}ms.", unloadViewInclusiveTime));

        }

 

This conclusion lead us to think of another way to reduce the unload overhead. So I came out with the following simple solution: Instead of using ContentControl as the view place holder, use Border!

Surprisingly or not, here are the results:

Direct Indirect Efficient
84 101 56
90 105 64
84 120 73
77 104 62
86 98 71
91 101 64
106 108 70
104 128 66
93 115 66
90 110 63
Average 90.5 Average 109 Average 65.5

* Efficient is the Border test

 

As you can see in the table above, it looks like using a Border is somehow much faster than using a ContentControl.

Here is my tester.

Published Thursday, September 17, 2009 9:25 PM by Tomer Shamam
תגים:, , ,

Comments

# re: WPF Performance Sweets – ContentControl (Part 2)

Friday, September 18, 2009 4:34 AM by Rob

Great!  Thanks for following up that last post.  The good news for me is that I don't have to rework parts of Caliburn.  I tried it's view strategy out with Borders  as you suggested and everything works well in both WPF and Silverlight.  So, it's not a matter of changing the framework, but educating developers about this interesting nuance.  Thanks so much for putting in the work to figure this out!

# re: WPF Performance Sweets – ContentControl (Part 2)

Tuesday, September 22, 2009 8:20 PM by Tomer Shamam

You welcome Rob.

A little thing you should be aware of:

Now that you're using Border instead of ContentControl as the view place holder, you'll not be able to place a Presenter as the "content" of the border, having a DataTemplate for displaying it, since Border only supports UIElement as its child.

Please let me know if its a design issue. Maybe I'll come out with something.

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above:
Powered by Community Server (Commercial Edition), by Telligent Systems