Windows Form Controls vs WPF Controls Part-2 (Performance Comparision)

The article is about windows form controls and WPF controls performance.

Introduction

This is the analysis of the Windows form controls and WPF controls and how they are loaded in the system. It dives deep into the processes being invoked and time consumed by both the application types.

Background

The last article explained about memory consumption of windows and wpf application, now let us dive deep into the performance related aspects and compare the processes involved.

Using the code

The code is same as the previous article but just to summarize :-

To compare both the Application Types we would require the applications to be created with similar controls .

For this example, I have taken TextBox control. Reason for choosing TextBox controls is because in

Windows Form Application TextBox Class is inheriting from System.Windows.Forms.Control in System.Windows.Forms.dll

WPF Application TextBox Class is directly inheriting fromSystem.Windows.Controls.Primitives.Control (PresentationFramework.dll)  

Due to this the TextBox control in WPF does not inherit from ContentControl thus avoiding an extra overhead of object creation.

Arguably, We could have used Windows form Label with TextBlock but lets use TextBox since almost all real world applications will use it somewhere or the other. 

To begin with we will create 1000 TextBox objects on windows form and WPF application and render them on screen.

Let's create a a simple windows form application and add the following code into it.

  1. using System.Drawing;  
  2. using System.Windows.Forms;   
  3.   
  4. namespace WindowsFormsPerformance  
  5. {  
  6.     public partial class WindowsForm : Form  
  7.     {  
  8.         private System.Windows.Forms.TextBox textbox1;  
  9.         int Iteration = 1000;  
  10.   
  11.         public WindowsForm()  
  12.         {  
  13.             InitializeComponent();  
  14.             CreateMultipleTextControls();  
  15.         }  
  16.   
  17.         public void CreateMultipleTextControls()  
  18.         {  
  19.   
  20.             for (int i = 0; i < Iteration; i++)  
  21.             {  
  22.                 this.textbox1 = new System.Windows.Forms.TextBox();  
  23.                 this.textbox1.Location = new System.Drawing.Point(10, 10);  
  24.                 this.textbox1.Name = "textbox" + i;  
  25.                 this.textbox1.Size = new System.Drawing.Size(150, 150);  
  26.                 this.textbox1.BackColor = Color.Blue;  
  27.                 this.textbox1.TabIndex = 0;  
  28.                 this.textbox1.Text = "textbox";  
  29.                 this.Controls.Add(textbox1);  
  30.             }  
  31.         }  
  32.     }  
  33. }   
Let's create a a simple WPF application and add the following code into it.
  1. using System.Windows;  
  2. using System.Windows.Controls;  
  3. using System.Windows.Media;  
  4.   
  5. namespace WPFWinPerformance  
  6. {  
  7.     public partial class MainWindow : Window  
  8.     {  
  9.         int Iteration = 1000;  
  10.         private TextBox textbox1;  
  11.      
  12.         public MainWindow()  
  13.         {  
  14.             InitializeComponent();  
  15.             CreateMultipleTextControls();  
  16.         }  
  17.   
  18.         public void CreateMultipleTextControls()  
  19.         {  
  20.             for (int i = 0; i < Iteration; i++)  
  21.             {  
  22.                 this.textbox1 = new TextBox();  
  23.                 this.textbox1.Name = "textbox" + i;  
  24.                 this.textbox1.TabIndex = 0;  
  25.                 this.textbox1.Text = "Text";  
  26.                 this.textbox1.Width = 150;  
  27.                 this.textbox1.Height = 150;  
  28.                 this.textbox1.Background = new SolidColorBrush(Colors.DarkBlue);  
  29.                 this.textbox1.Margin = new Thickness(10, 10, 10, 10);  
  30.                 this.Grid1.Children.Add(textbox1);  
  31.   
  32.             }  
  33.         }  
  34.     }  
  35. }  
To measure the performance the tool used is Profiler in Visual Studio 2015. In profiler the results are captured using options like CPU usage (Windows Forms & WPF) and Application Timeline (WPF).

Results

Lets compare the results to find out where actually the most time spend in the application.

Windows Form Application Result


WPF Application Result


The above result shows that Windows Form Application takes 5.642 secs. to load up and WPF application takes only 4.156 secs which shows that WPF is much faster than Windows in terms of load time. But we need to dig out the reason why is it so? In both the applications some non native code is taking approx. more than 90% of the CPU time. In windows form application the constructor and textbox creation method is taking around 11% of the CPU time whereas in WPF application it is just 0.23%. To get another view lets check out the hot paths in the application.

Windows Form Application Result

WPF Application Result

From the above results it is bit clear now that which code is taking most of the CPU time and in both the application types it is Application.Run method. The Application.Run method in short is responsible for creating a message loop which is used for catering the application events. The message loops calls window procedures which are responsible for processing the messages. To identify these window procedures lets go into process level.

Windows Form Application Result




 
 

The above result shows that process like CreateWindow, Comctrl32.dll are taking approx. 70% of the CPU time. Comctrl32.dll (Common Controls library) has the controls which provide distinctive look to all windows applications since Windows form application uses default windows controls provided by the windows operating system; it is obvious that Comctrl32.dll process will be invoked. CreateWindow is a method which creates the window for the application. These both processes are necessary in Windows Form application since its framework heavily relies on it. Now lets see which processes are used by WPF internally. In Visual Studio 2015 a feature to check the Application Timeline is provided for WPF applications. This gives more clearer picture of what is happening internally.  


 

Here we can observe that first the parsing of XAML content is done, then followed by Layout Creation which includes the visual tree formation and then Render. The rendering is done using Direct 3D which can be observed by a call to wpfgfx.dll.


To summarize the findings, it can be seen that windows form dependency on Windows API like comctrl32.dll and slower rendering is leading to increase in application load time as compared to WPF. That could be explained because of the rendering modes of WPF and Windows forms.

  1. WPF uses retained rendering and Windows Forms uses immediate rendering.
  2. Rendering on WPF is done on composition thread which is different than UI thread
  3. GPU is used in WPF applications which accelerates the rendering process.

The above tests were carried on Windows 10 Operating System and I3 processor, the results might vary on older operating systems.

Coding is Simple