Showing posts with label performance. Show all posts
Showing posts with label performance. Show all posts

Thursday, October 31, 2013

EventSource & Performance for High Volume Events

.net framework 4.5 introduced EventSource API to write events using ETW infrastructure. The choice of ETW infrastructure has made the writing of events lightning fast. Now they can be consumed by any ETW consumer. If the event provider is not enabled, then the events just fall on the floor. On the other hand, if a session is already established, they are written to ETW session buffers. Now they can be consumed by the consumers. The event provider (EventSource) doesn't really have to wait until the messages are consumed. This is independent on the number of consumers registered for a particular type of events. We have discussed about ETW tools and their usage with EventSource API [Reference].



As we discussed above, the choice of ETW infrastructure has made EventSource API extremely fast. But we can even improve on it further. But remember that these recommendations would be useful in the case for high volume events generally. For low frequency events, although you would have performance improvement, but this might not be very noticeable.

Optimization # 1: Use IsEnabled() before WriteEvent()
ETW controllers can enable a provider before registration of provider. So when a provider registers itself and starts emitting events, a session is automatically created and they are forwarded to the buffer. In order to prove that, we can start Semantic Logging Service (from Application Block) and then run our application. Our service should still be able to consume the events. On the other hand, if the provider is not enabled, the events just fall on the floor by the ETW infrastructure. In order to improve it, we can check if the event provider is enabled so that we don't even use the WriteEvent() definition in base class. It does check the same thing in the base class as well.

When an Event Provider is enabled (generated for EventSource), it receives a command to enable itself. We can even use this command in our custom EventSource by overriding OnEventCommand() method. You don't need to use the definition of base class method as there is an empty implementation of the virtual method.



It caches this in a local variable. So EventSource can use this field to check if it is enabled. There is no property available in EventSource type to check that but we can find IsEnabled() method to do just that. Now a method might cause some confusion for you thinking it might be slow as it might do some other stuff and could slow it down further. As the development team suggests, it is just a field fetch. We can also verify this by dotPeeking into the framework assembly from Windows folder.



As a matter of fact there are two overloads of the method. One of these overloads is parameter less. The other one is more interesting, it lets us check if the provider is enabled for a particular level and keyword, which makes it more interesting.



Optimization # 2: Convert static field fetch to local member fetch
This suggestion is not for EventSource implementation but it refers to the use of EventSource instance in the logging site. The logging site is the code from where we call EventSource's methods. As we have seen several examples in this blog, EventSource implementation is singleton based [See singleton], it is a static variable fetch at the call site. Here is an example of the usage:



As we know static variable fetch is more expensive than an instance member fetch, we can assign the singleton instance to a local instance member. In order to improve the usage of EventSource's method, we can assign this to a local variable. Then we can use the local member at the logging site.



Optimization #3: Minimize the number of EventSources in the application
In a previous post, we discussed about the mapping between EventSource and ETW Event providers. Actually the framework registers an Event Provider in ETW infrastructure for every EventSource in the application. This is done using ETW EventRegister API. This allows the framework to pass a command to the EventSource from external controllers.

The framework also maintains a list of EventSources in the application domain. We can get the list of all EventSource (s) in the application domain using the static GetSources() method in EventSource type.



Both of these tasks are performed at startup. Since this would depend on the number of EventSource (s) in the applications so the higher number for event sources in your application would mean slower startup. This can be resolved by minimizing the number of EventSource in your application. I would definitely not suggest an EventSource for each type in your application. There can be two options to resolve this.

The first option is using Partial types. We can span the same type across different files in the same assembly. All of these definitions are combined to generate a consolidated type by the compiler. We generally organize our types in different folders in a project. Here each folder generally represents types belonging to the same group. We can provide all the event methods definition for the method group for the types in this folder.

Most of the real life projects span more than one projects. In this case, we should still be able to minimize the number of EventSource (s), by defining on for each group, in order to improve the startup performance. Here each event source can take care of instrumentation requirement for a group of types in your application. You can group them logically or the way you want.

Optimization # 4: Avoid fallback WriteEvent method with Object Array Parameter
There are various overloads of WriteEvent() methods in EventSource type. We need to call WriteEvent() method from our [Event] methods in EventSource type. One of these overloads is an overload with params array. If none of the overload matches your call then the compiler automatically falls back to this overload.



We should be avoiding the fallback method as much as possible for performance reasons as it is reported to be 10-20 times more expensive. This is because the arguments need to cast to object, an array needs to be allocated and these casted arguments are added to the array. Then calling the methods with these arguments as serialized.

In order to avoid using the fallback overload, we can introduce new WriteEvent() method by overriding it.

Sunday, February 3, 2013

[MPGO] Managed Profile Guided Optimization - .net framework 4.5

In the previous post we discussed about what are native assembly images and how it can help us in improved application startup and facilitate code sharing. In this post, we are going to discuss another CLR feature provided in .net framework 4.5. The feature is called Profile Guided Optimization. The only difference is that this profiling would not be based on historical usage of the application by the user but would be based on some test scenarios. The profile optimization is about improving JIT compilation, on the other hand, profile guided optimization is improving the performance by the layout of native assemblies.

It must be remembered that this is the same optimization that is used by .net framework assemblies. Profilers have been helping the software developers with code optimization. They are used to measure various statistics for the running software including memory footprints, memory leaks, CPU and I/O usage. The feature just creates the profile data for assemblies for generation of better native binary images by NGEN [Native Image Generator].

How it works?
The workflow involving the use of MPGO is very simple. It is fed with the list of IL assemblies with the scenarios to run. It generates the updated IL images in the specified folder. The simplified workflow can be presented as follows:


The first part of this procedure happens on vendor side creating providing the software. The vendor uses [MPGO] and associates profile data with the IL assemblies. Now the assemblies are provided to a client in a deployment package. Here they can be NGENed manually during installation. They can also be queued for NGENing for later when the machine is idle to be taken care of by Native Image Service [ Or Native Image Task for Windows 8 machines]. They can also be automatically NGENed by the framework when no such specification is provided by the installation package.

Running MPGO
MPGO can be used with Developer Command Prompt for Visual Studio 2012 Ultimate. Please make sure that you are running the command prompt with administrator privileges.


It might ask for administrator privileges if your Developer Command prompt is not running with it. You will get an access denied for not granting them.


MPGO & Application Types
It must be remembered that neither the native images nor MPGO are the silver bullets to improve application performance. They are recommended for very large applications where start-up time can be an issue. It must be remembered that they are only recommended for desktop applications. Both of these tools are not recommended for ASP.net and WCF applications because of their dynamic deployment model and significantly less importance of start-up time for those application types. MPGO is not supported for Windows Store apps.

MPGO & Application Deployment
As we have discussed MPGO requires Visual Studio 2012 Ultimate license. Our clients definitely wouldn't have this license on their machines. Actually they don't need to and this tool is also not part of .net framework. It's rather a Visual Studio tool. We can create IL assemblies optimized through MPGO. We can include these assemblies in our deployment package. While installation we can run NGEN to copy these assemblies to the native image cache for manual native images creation.

If your clients are Windows 8 machines, then these native images can also be automatically created when the application is running for future application startup performance gain.

Using MPGO:
Let's use some existing code for doing some cool stuff with [MPGO]. We can use the project from one of our previous posts. This is the project we developed while discussing Portable Class Libraries in the context of MVVM based designs. You can find the project here. You can also download the code.

We will be setting the output folder for all the projects in the solution to [././ILAssemblies]. This would create a folder on the same level as [bin] folder.


This is where all the assemblies would get copied once you build the project.


Let's create another folder where we you want the optimized image of the assemblies is copied to. The optimized assemblies would be generated by [MPGO].


Running MPGO is easy. We need to specify the required switches to help the tool. Here we are running it for the assemblies (including DLLs and EXEs) in [ILAssemblies folder). We are generating the optimized images in [OptimizedILImages] folder. [Scenario] specifies how we want to run our application including the start-up arguments. The other option is to use the profile data from some other assemblies. In that case, we don't need to run the application. This is supported through another switch [-Import]. Please remember that [-Scenario] and [-Import] are used exclusively.


When we run this, MPGO launches the application. We need to run the application through the pre-thought scenarios and close the application. As soon as we close it, MPGO has all the data to optimize the application (alternatively it also supports Timeout where it would just profile it for the specified duration and uses the profile data). So it runs our [Coffee House App] as follows:


As soon as we close the application, we have our optimized assemblies in the [OutDir] folder.


[MPGO] doesn't override the optimized assemblies in the [OutDir] folder. It just appends them with the next available integer. In this case, I have run the tool again and look at how it has appended "-1" to the name of the assemblies.


[Note] I don't want you to miss one important detail. Two of these assemblies are portable class libraries. It is really great to see that the tool supports them for generation of optimized images.

Mechanism of Optimized Assembly Generation
This should be enough to discuss about the tool. But we need to see what is happening under the hood. Let's discuss briefly what is actually happening under the cover. When we run MPGO it basically compiles our assemblies and their dependencies into native code using NGEN and copies only the native images of source assemblies in the [OutDir] folder.


We can use Process Explorer to see how MPGO is using NGEN to created native images. Remember we discussed about MSCORSVW.exe in the previous post?


You can see the details about the assemblies in registry as follows:


When compilation of these assemblies finishes, [MPGO] adds instrumentation information to those assemblies.


After instrumentation of the assemblies, MPGO launches the application as specified in [-Scenario] switch. It is launched from the source directory. It is done for assemblies individually as they are individually compiled they are picked up for instrumentation.


It then runs the application with the scenario. It waits until the application finishes or timeout expires. During this time, MPGO profiles the application and keeps the details in a temporary storage. The tool creates IBC data files in the [OutDir] folder. They are saved with [IBC] extension as follows:


As soon as the scenario finishes or timout expires, the instrumentation assemblies are uninstalled.


Since MPGO has profiled the application while running the scenario, it just copies the assemblies from the source folder and merges the profile data with the assemblies. It then removes the IBC data files. Now we have the assemblies with the profile data.


Using Optimized data from Previously optimized Assemblies
Once we have the optimized assemblies with the profile information, we don't need to run the scenario every time there is a new version of the assembly is created. We can just source the profile information from previously optimized assemblies and create newer version of the assemblies for native image generation. Let's create another image, called [ReOptimizedILImages], in the same folder as follows:


We can specify the new versions of assemblies with -assemblyList or -assemblyListFile switch. The ones to use the scenarios from could be provided with -Import switch. MPGO processes it and generates the newer versions of assemblies in -OutDir folder.


Here is how we can specify the same in Command Prompt.


Finally we have the merged assemblies in the [-OutDir] folder.


It must be remembered that if an assembly (specified in -assemblyList / -assemblyListFile) has no corresponding assembly in the assemblies containing the profile data (specified as -Import) then it would just fail for the particular assembly. The rest of the assemblies still get merged successfully. In order to see that let's just remove [CoffeeHouseApp.PortableViewModels] assembly from the [-Import] folder. Now execute the same command as above and notice the output in command prompt.


MPGO In Enterprise Eco System
In the enterprise world, MPGO might be made part of the process. As you know we first need to run scenarios. This can be done on a sample machine. Running the scenarios on an application would created assemblies with the profile data. These assemblies can be uploaded to some central location (Or checked into a source control).

Now Build servers (like TeamCity / Cruise Control) come into action. We can make this as one of the last build steps. We can use the -assemblyList from the repository assemblies from current build and provide the -Import details as the checked-in assemblies. Now when MPGO is run, it would create the merged assemblies in the specified folder. It would be tricky though in case of Build Triggers and dependencies if this build would be triggering some other builds on the build server.

[Note] If we are using Visual Studio, we can include a post-build event with MPGO command and have the merged assemblies in the specified folder.

Thursday, January 31, 2013

Native Images of Assemblies - .net framework 4.5

In the previous post we discussed how we can improve JIT compilation of .net code by using ProfileOptimization for multicore machines in a .net framework 4.5 application. In this post we are going to discuss another CLR area improved in .net framework 4.5. In the next post, we going to discuss the new tools available in Visual Studio 2012 to further improve this. This discussion is about Native Images of assembly, why we need them and how to write better native assemblies.

What are Native Assemblies?
In the last post we discussed that IL code is compiled into Native code by JIT compiler when the process is being run by CLR. So a natural thought could be what if we could do this compilation before hand and generate the native images. We can use this native image when we actually need them in a process. It would be even better if this image could be shared by various application domains. As a matter of fact, native assemblies in .net fulfills this wish list. Not only they support the native image of a specified assembly, they also support creation of native images of other dependent assemblies.


As we know that JIT compiled image of methods is kept in the memory space of the running process, so creating native images upfront would reduce the memory footprint of the process. This compiled image would also be shared by all the processes requesting the same assembly, hence no process need to JIT compile it separately [as they are Windows PE files] and the proceses could share this, improving the overall system performance. Additionally this would improve the startup time of the process. In addition of time saved for JIT compilation, they also don't require any type safety verification.

Native Images Storage
NGEN [Native Image Generator] creates native image of a managed assembly and installs them to Native Image Cache. This is a reserved area in GAC [Global Assembly Cache]. So this might also be treated as a Time Vs Space trade-off where we sacrifice the hard disk space for the gains in the time saved during the process execution.


You should be able to find them in %WinDir%\assembly\NativeImages_RUNTIMEVERSION.



It must be remembered that these directories not visible in Folder explorer. We can check the contents of the folder in command window though.

Life Time of Native Images
Now let us discuss if these native images last forever on the machines and if and when they can be removed form the machine. This is called reclaiming the images. Before .net framework 4.5 and Windows 8, these images can be claimed manually using NGEN Unistall command. The command can be part of application uninstaller package.

The new framework also supports this for the images installed manually on Windows 8 operating system. For the images created automatically can be claimed automatically by the operating system if they haven't been used for a long time creating more free space for the more frequently used stuff on the machine. These are claimed by Native Image Task during the idle time.

User Level Native Images & Application Container level Native Images
For Windows 8 and later versions of the operating system, .net framework 4.5 supports creation of user and application container based native images. So if a machine is shared between different users, the native images can be made to not share between different user profiles.

Deciding IL Vs Native Images
From the above description it seems that NGENing assemblies would always be beneficial as we are bypassing the JIT compilation when the application is running. Is it really so? NGEN.exe is only for assemblies which run in a full trust scenario. If they are referenced in an application running in partial trust then their non-native version is loaded which goes through JIT compilation.

CLR puts the validation of strong named assemby under extra test which are not in GAC. so if our native image is for a strong assembly [not in GAC], we might not get any benefit as the CLR would still touch every page of the assembly which would nullify any gain caused by NGENing the assemblies.

Native Image Generator [NGEN.exe]
.net framework provides NGEN [Native image GENerator] for assembly's native image generation based on the processor architecture based instruction set. Once we have the native image of an assembly, it doesn't need to be JIT compiled when the application is running, improving the performance of the application. Native Image Generator can be launched using Developer Command Prompt in available with Visual Studio 2012 or Windows SDK Command Shell. For Visual Studio 2012, it appears in the start menu as follows:


The tool supports both installing and uninstalling native images from the native image store. The help about NGEN commands can be obtained by using /? switch with the executable as follows:


Deferring Native Image Generation
Native Image generation work can also be deferred up to when machine has some idle time. This is actually done by queuing up the NGENing of an assembly. This is then taken care of by Native Image Service. This is also used to update the native images because of other related dependencies updates including any updates in .net framework. This service can stand multiple machine reboots as it stores its state. Installation scripts can use NGEN.exe to queue up items for Native Image Service for low priority NGENing running with administrator privilege (which is a general requirement for running NGEN.exe for creating native images). The installer first copies the assembly to the application folder and then uses NGEN to queue up item for deferred NGEN using Native Image Service or Native Image Task based on the operating system you are doing the installation.


For Windows 8 onwards, the responsibilty of NGENing the queued up assemblies is taken over by Native Image Task. This task also support the automatic native image generation and reclaim for an assembly. [http://msdn.microsoft.com/en-us/library/hh691779.aspx]. The automatic NGEN is only for assemblies targeting .net framework 4.5 or later, plus it must have been installed in GAC or Windows Store App package. The automatic native image generation is achieved by the .net framework by tracking down the JITing of an assembly. They are queued for NGENing when the machine is idle.

Assembly Probing and native images
We have discussed in the past how we can determnine the assemblies loaded by an application using Fusion Log Viewer, Process Explorer, List DLls and Visual Studio Modules window [http://www.shujaat.net/2012/04/fusion-log-viewer-fuslogvw-for-assembly.html]. We know that these assemblies can be loaded from different locations which are searched in a predefined fashion. An application can go through a list of steps to locate the requested assembly. This is called Assembly Probing. You can find the details of the process here [How the Runtime Locates Assemblies]. We must remember that they require the application to be running in [Full Trust] for .net framework 4.0 onwards. But after .net framework 2.0, these assemblies can be shared across application domains, plus we don't need to individually NGEN assemblies, while doing this, we can also NGEN their dependencies if they are available in assembly manifest.

Native Image Generation Log
.net framework also supports generation of logs for native images generation of assemblies. These logs can be used for troubleshooting any possible issue when needed. The logs are created in the .net framework folder in %WinDir% folder as follows:


It seems that the log for NGEN service is maintained separately. You can see the NGEN service log as well in the above snapshot. The contents of the log are as follows:

The verbosity of the logs can be controlled using HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\NGenLogVerbosity registry entry. The supported values are 1, 2 and 3. The default value is 2 which is also used in the absence of this registry entry. .net framework 4.5 also caps the size of this log for computer wide [1MB], user [500KB - Win8 only] and app container [100KB - Win8 only] specific native image generation. The details can be found here: [http://msdn.microsoft.com/en-us/library/hh708846.aspx]

MSCORSVW.EXE
MSCORSVW.exe is used to compile the .net assemblies to native images in the background. You might have seen some threads specially discussing and asking question specially about this executable. Actually you can find the executable in the following folder:



The remedy to get rid of this process is to finish all the queued up items waiting for getting compiled as discussed here:[http://blogs.msdn.com/b/davidnotario/archive/2005/04/27/412838.aspx]. Although this is an old post but it should still be valid.

Native Images and Windows App Store Packages
As we discussed before, Windows 8 supports automatic creation of native images for public assemblies. This is actually one of the App certification requirement for a Windows Store App. This is part of performance test, you can find it here: [http://msdn.microsoft.com/en-us/library/windows/apps/jj657973.aspx#performance_test]. We can also opt-out for this automatic native image generation by including nongen.txt file in our App package.

Linking Native Images with IL Assembly Image
[Erez Metula] has an amazing description of how native images are linked by IL assembly images by .net framework [Chapter 8]. The book is available on amazon and rightly deserves the rating. The book was released in November, 2011, so it discusses the features with .net 3.5 SP1 context [.net v4.0 - released: 3,2011]. But most of the stuff is still valid.


Here IL contains the details of the assemblies which have their native images already created in the cache. NI has further details about the native images identified by [MVID].

Friday, February 25, 2011

WPF - Performance Improvement for MVVM Applications - Part # 2

This is the second part of our discussion about performance improvement of an MVVM based application. You can find the other part of this discussion here:

- Part - 1: http://shujaatsiddiqi.blogspot.com/2011/01/wpf-performance-improvement-for-mvvm.html

- Part - 3: http://shujaatsiddiqi.blogspot.com/2011/03/wpf-performance-improvement-for-mvvm.html

In this example we would see how we can utilize Lazy Initialization to improve the performance of MVVM based application. Lazy initialization is a newly available features of .net framework 4.0. As I remember this is based on Tomas Petricek's suggestion which has been incorporated in .net framework recently. This is a part of effort to incorporate lazy execution in c# code. You might already know that LINQ queries support lazy evaulation already. They are only evaluated when the first time they are enumerated. If they are never enumerated then never such evaluation takes place. With new Lazy initialization feature, the framework now also supports lazy initialization.

http://msdn.microsoft.com/en-us/vcsharp/bb870976

In this example we would base our discussion on a hierarchical view model. The main view is consisted of some collection based controls. Each of these control also needs to define its template to specify how different items in the collection would be displayed on the screen.

Let's consider a view for a Course with just two students. The data of students should be displayed in tab items in a TabControl. The student information should only have two fields, their first and last names. Student's First name should be displayed as header of its TabItem. If the data is not entered yet then it should display "Default" in the header. The XAML definition of the view is as follows:
<Window x:Class="WpfApp_MVVM_LazyInitialize.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp_MVVM_LazyInitialize"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>        
<TabControl Height="288" HorizontalAlignment="Left" Margin="12,12,0,0" Name="tabControl1" VerticalAlignment="Top" Width="480"
ItemsSource="{Binding StudentViewModels}" >
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding StudentFirstName}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>                
<DataTemplate>
<Grid>
<Label Content="First Name" Height="27" HorizontalAlignment="Left" 
Margin="12,29,0,0" Name="label1" VerticalAlignment="Top" Width="105" />
<TextBox Height="30" HorizontalAlignment="Left" Margin="123,29,0,0" 
Name="textBoxFirstName" VerticalAlignment="Top" Width="345" 
Text="{Binding Path=StudentFirstName}" />
<Label Content="Last Name" Height="27" HorizontalAlignment="Left" Margin="12,65,0,0" 
Name="label2" VerticalAlignment="Top" Width="105" />
<TextBox Height="30" HorizontalAlignment="Left" Margin="123,65,0,0" 
Name="textBoxLastName" VerticalAlignment="Top" Width="345" 
Text ="{Binding StudentLastName}" />
</Grid>                    
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</Window>

We would be needing two DataTemplates for TabControl. One is for Header i.e. ItemTemplate and the other is for the content of each TabItem i.e. ContentTemplate. The ItemsSource of this TabControl is bound to StudentViewModels collection. Each member of this collection should have atleast two properties StudentFirstName and StudentLastName. The ItemTemplate is just a TextBlock. The Text property of this TextBlock is bound to item's StudentFirstName property. The ContentTemplate has two TextBox(es). One of them is bound to StudentFirstName and the other is StudentLastName properties. We have kept the code behind of the view as default.

The DataContext of the above view is set as a new instance of MainWindowViewModel. It implements INotifyPropertyChanged so it needs to provide definition of PropertyChanged event as part of its contract. As required by the view, it provides a collection StudentViewModels. It is provided as an ObservableCollection. Each member of this generic collection is specified as of the type StudentViewModel.
class MainWindowViewModel : INotifyPropertyChanged
{
ObservableCollection<StudentViewModel> _studentViewModels = 
new ObservableCollection<StudentViewModel>();

public ObservableCollection<StudentViewModel> StudentViewModels
{
get
{
return _studentViewModels;
}
}

public MainWindowViewModel()
{
_studentViewModels.Add(new StudentViewModel());
_studentViewModels.Add(new StudentViewModel());
}

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

In the constructor of the above view model we have added two members to the collection. As expected they are of type StudentViewModel. They would be displayed as Tab items in the view. The definition of StudentViewModel is as follows:
class StudentViewModel : INotifyPropertyChanged
{
Lazy<Student> _model = new Lazy<Student>();

string _studentFirstName;
public string StudentFirstName
{
get { return _studentFirstName; }
set
{
if (_studentFirstName != value)
{
_studentFirstName = value;
_model.Value.StudentFirstName = value;
OnPropertyChanged("StudentFirstName");
}
}
}

string _studentLastName;
public string StudentLastName
{
get { return _studentLastName; }
set
{
if (_studentLastName != value)
{
_studentLastName = value;
_model.Value.StudentLastName = value;
OnPropertyChanged("StudentLastName");
}
}
}

public StudentViewModel()
{
_studentFirstName = "Default";
}

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

As expected by the view it has two properties StudentFirstName and StudentLastName. It implements INotifyPropertyChanged to support change notification.

The above view model uses Student as model. When the view model receives updates in these properties through WPF Biniding System, it just passes on those updates to the model. The instances initialized with Lazy initialization feature are accessed using Value property of the Lazy object reference. We have accessed StudentName and StudentLastName properties using the same. Let us assume that it were a model which requires a heavy instantiation. We are just displaying a MessageBox in the constructor. This would show a MessageBox from the constructor. In this way we would realize exactly when the constructor is called. This is how are trying to understand Lazy initialization of Student.
class Student
{
public string StudentFirstName { get; set; }
public string StudentLastName { get; set; }

public Student()
{
MessageBox.Show("Student constructor called");
}
}

Now let us run this. The application is shown as follows:



Enter some data in the First Name field of the first Tab Item. As soon as the focus is changed to the other field, the default Binding of Text property of TextBox triggers the source updates on LostFocus.


When you close the message box you can see the header of the TabItem being updated with the FirstName you entered.



Deciding which Constructor to use for initialization:
We can also decide which constructor of the type we want to use for initialization using the constructors of Lazy class. Lazy<T> allows Func<T> delegate as argument in some of its overloads.

In a multithreaded scenario:
In a multithreaded scenario the first thread using the lazy instance causes the initialization causes the initialization procedure and its value would be seen by the other threads. Although the other threads will also cause the initialization but their value will not be used. In a multithreaded scenario, like this, we can use any overload of EnsureInitialized method of Lazyintializer for even better performance. This can also use any of the default constructor or specialized constructor using Func delegate.

http://msdn.microsoft.com/en-us/library/system.threading.lazyinitializer.ensureinitialized.aspx

Download Code:

Wednesday, January 26, 2011

WPF - Performance Improvement for MVVM Applications - Part # 1

This is a series of posts about performance improvements of an MVVM based applications. You can find the other posts here:

- Part 2 : http://shujaatsiddiqi.blogspot.com/2011/02/wpf-performance-improvement-for-mvvm.html

- Part 3: http://shujaatsiddiqi.blogspot.com/2011/03/wpf-performance-improvement-for-mvvm.html

In this example we are discussing the various performance improvement for a WPF Binding developed using MVVM. This is for enhancing user experience by increasing the responsiveness of the system. MVVM based application is highly dependent upon the WPF Binding system. I think if we use certain features of Binding system then we can achieve this.
<Window x:Class="WpfApplication_ASync_Binding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication_ASync_Binding"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<TextBlock  Height="56" HorizontalAlignment="Left"
Margin="40,71,0,0" Name="label1" VerticalAlignment="Top"
Width="434" Background="Aquamarine" >
<TextBlock.Text>
<Binding Path="StudentName" StringFormat="testtt:{0}" />
</TextBlock.Text>
</TextBlock>
</Grid>
</Window>

We are not changing the code behind of the view so it should be as created by default. The view model:
namespace WpfApplication_ASync_Binding
{
using System.ComponentModel;

class MainWindowViewModel : INotifyPropertyChanged
{
private Student _student;
public MainWindowViewModel()
{
_student = new Student();
} 

private string _studentName;
public string StudentName
{
get
{
return _student.StudentName;
}
set
{
_student.StudentName = value;
OnPropertyChanged(StudentName);
}
} 

public event PropertyChangedEventHandler PropertyChanged; 

private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

The view model is using _student as model. This is an instance of Student class. As you can see StudentName is just a proxy property for the model’s property named StudentName. The definition of Student is as follows:
namespace WpfApplication_ASync_Binding
{
class Student
{
public string StudentName { get; set; } 

public Student()
{
StudentName = "Muhammad";
}
}
}

Let’s run this application. The output should appear as follows:


Now let’s change this a bit. Let’s consider Student is using some complex logic for its property StudentName. It might be using a web service which might be slow. Now since we are using proxy property for binding this delay would slow down the binding and the form would become idle. Let’s create this scenarios by just introducing a delay using Thread.Sleep() as follows:
namespace WpfApplication_ASync_Binding
{
class Student
{
private string _studentName;
public string StudentName
{
get
{
//imaginary delay
Thread.Sleep(10000);
return _studentName;
}
set { _studentName = value; }
}

public Student()
{
StudentName = "Muhammad";
}
}
}

Now run the application. The same form would display but after a delay of atleast 10 seconds.

Basically when Binding system would access the getter for StudentName property in the DataContext. It would be delayed because the view model would be trying to get the Model’s property resulting in a delay of atleast 10 seconds (because of Thread.Sleep). So form instance is created. It assigns the DataContext as MainWindowViewModel in InitializeComponent. When it attempts to bind the Text property of TextBlock. It experiences this delay. So the delay is because of binding. If this binding becomes asynchronous then the performance could improve. You should be glad to learn that WPF Binding system supports making its binding asynchronous by providing IsAsync property in Binding markup extension. Let’s use this!

We update the view as follows:
<TextBlock.Text>
<Binding Path="StudentName" StringFormat="testtt:{0}" IsAsync="True" />
</TextBlock.Text>

Now run this. The form appears as follows:


This would be shown like this for atleast 10 seconds. During this time, it starts a ThreadPool thread on the background to get the Binding source. As soon as the source property becomes available, the binding updates the view as follows:


Well this is good but user sees nothing on the screen for atleast 10 seconds. We might want to show something else to the user until the data becomes available as a fallback mechanism. WPF binding system supports that too. You can achieve that by setting FallBackValue propery of Binding as follows:
<TextBlock.Text>
<Binding Path="StudentName" StringFormat="testtt:{0}"
IsAsync="True" FallbackValue="Test Fallback value" />   
</TextBlock.Text

Now run the application. The window is shown as follows:


This is shown like that for 10 seconds showing the Fallback value for Binding. You can see that StringFormat is not applied for FallbackValue. After 10 seconds, it updates itself as follows:


In order to have more sophisticated fallback mechanism, you might want to consider Priority Binding.

http://shujaatsiddiqi.blogspot.com/2010/09/wpf-priority-binding.html

The world is not simple. Let’s make it a little complex by updating the constructor of our model (Student) as follows:
public Student()
{
StudentName = "Muhammad";
Thread.Sleep(20000);
}

This is to simulate the 20 seconds further delay in Binding. Let’s run the application. For 20 seconds, nothing appears on the screen. After that the window appears with the fallback value. The fallback value remains on the view for 10 seconds. After that the view is updated with the finalized value for StudentName with applied StringFormat. Now the main question is why this window appears after 20 seconds when binding is asynchronous. Basically Binding.IsAsync just makes the Binding asynchronous. If there is a delay in the construction of DataContext, this would still be on the UI thread hence synchronous. The construction of DataContext (MainWindowViewModel) is causing this delay because of delay of instantiation of the Student (model) in the constructor of view model [Thread.Sleep(20000)].

In order to improve this behavior we can update the way DataContext is constructed. We can construct the object using ObjectDataProvider. This is to utilize the asynchronous instantiation feature of ObjectDataProvider. We can cause asynchronous construction by setting IsAsynchronous for ObjectDataProvider. Let’s update the definition of the section of XAML for view where we are assigning DataContext as follows:
<Window.DataContext>
<ObjectDataProvider ObjectType="{x:Type local:MainWindowViewModel}" IsAsynchronous="True"  />
</Window.DataContext>

Now run the application. As we run the application there is no delay and the following screen appears:


This is maintained for 30 seconds. The 20 seconds is for the construction of DataContext (causing construction of model) and the other 10 seconds is for the delay in the getter for StudentName property from DataContext. Basically the Fallback value is maintained until the value is available no matter the delay is called by the DataContext construction or the available of its property.

10 + 20 = 30 seconds

Eventually the window is updated as follows:


Download: