XAF – Core & Performance Improvements (coming in v2011 vol1)

Introduction

Do you remember last great performance improvements we introduced in versions 10.1 and 10.2? Now, I’m pleased to report that the upcoming major release is no exception! You might already have heard some details on further improvements we planned for our framework in forums, but I want to fully devote this blog to describing what we achieved in this regard. So, let’s start!

Caching of metadata, explicit types registration…

Starting from version 11.1, the information about domain components as well as the application model is generated only once, during the first application run. Then, this information is automatically saved on the disk and loaded during subsequent application runs. So, don’t be surprised if you detect two service assemblies in the application folder after it is run for the first time. These are DcAssembly.dll and ModelAssembly.dll respectively. There will be also one more file without any extension – ModulesVersionInfo. Its purpose is to keep version information for modules used in your application. If you open this file in your favorite text editor, it may look like this:XAF_Rocket

\SystemModule 11.1.1.9
\XProjectModule 1.0.4134.34463
\SystemWindowsFormsModule 11.1.1.9
\TreeListEditorsModuleBase 11.1.1.9
\TreeListEditorsWindowsFormsModule 11.1.1.9
\FileAttachmentsWindowsFormsModule 11.1.1.9
\XProjectWindowsFormsModule 1.0.4134.34463

XAF uses the information from this file to decide whether cache assemblies should be generated or not. So, if the module versions remain unchanged, XAF will load ready information about domain components and application model structure from the DcAssembly.dll and ModelAssembly.dll libraries. Otherwise, it will remove existing cache assemblies (if found) and store the generated information on disk, and then update the information in the ModulesVersionInfo file (if it does not exist, it will be created).

I can anticipate the next question you want to ask: How much faster is this caching approach? We measured the startup time of several 10.2 applications and compared it with their respective 11.1 versions. The average improvement starts at 20%. It may vary from application to application though. In any case, we think that it is one more significant step forward in making XAF more user friendly, and we hope that end-users will notice this small improvement.

Some of you will remember our ambitious goal - halve the startup time, which we discussed in our Roadmap 2011. To be honest, we hoped that caching would help us eliminate more startup time, and when it did not, we of course researched other ways of doing this.

We have also optimized how the information about types (controllers, business objects, modules, etc.) is collected in XAF. As part of this, the ModuleBase class was greatly refactored and simplified. For instance, a bunch of properties like AdditionalBusinessClassAssemblies, AdditionalBusinessClasses, BusinessClassAssemblies, BusinessClasses, DeclaredBusinessClasses, as well as their respective virtual methods, were eliminated and replaced by a small set of *ExportedTypes members. In addition, the ModuleBase class now exposes a set of *ControllerTypes members. Both can be used to explicitly register business objects and controllers respectively, to be used by the module, instead of automatic searching for all the matched types within the module assembly. At once, we refactored all standard XAF modules to take advantages of these improvements. For example, this is what the registration code of the ReportModule looks like in 11.1:

  1: protected override IEnumerable<Type> GetDeclaredExportedTypes() {
  2:     return reportDataType == null ? new Type[0]: new Type[] { reportDataType };
  3: }
  4: protected override IEnumerable<Type> GetDeclaredControllerTypes() {
  5:     return new Type[] {
  6:         typeof(CustomizeNavigationItemsController),
  7:         typeof(InplaceReportCacheController),
  8:         typeof(PrintSelectionBaseController),
  9:         typeof(ReportDataSelectionDialogController),
 10:         typeof(ReportServiceController)
 11:     };
 12: }
You may ask what will happen to your custom modules? Will your custom controllers and business objects still be automatically collected and registered in 11.1? Yes, they will, but we recommend you perform similar refactorings in your custom modules. All these tricks are intended to achieve some additional improvements to the overall startup performance.

Future plans

As always, we do not plan to stop at what we already achieved, and you should expect more good news in future releases. One of our upcoming goals in this direction is to minimize the number of system assemblies used in XAF. Let’s imagine the worst case, and count the number of required assemblies for the needs of a single XAF application. We currently have about 50 system modules and each of them is represented by a separate assembly. Add to this the number of custom modules you might have already developed for your needs or the number of third-party assemblies like eXpand and finally the number of required DXperience assemblies, and it is easy to reach one hundred assemblies overall. This huge number is not only difficult to manage by developers, but it also can be a performance pitfall - the more assemblies, the more time CLR requires to load them. I am not even talking about the compilation time here. Hence, we want to make it possible to have more than one XAF module within a physical assembly. I cannot promise anything or say more at this time, but it is possible that one day we may literally have only a few assemblies, like DevExpress.ExpressApp.dll, DevExpress.ExpressApp.Win.dll, DevExpress.ExpressApp.Web.dll, containing all the necessary system modules. I think that would be paradise to manage and deploy for developersclip_image002.

Again, this is only current thought and we will have to wait for the final results of our research in this regard. Of course, we will also consider further how to optimize the types info subsystem, because populating it currently takes most of the startup time, and it seems that we have already reached the limits of .NET Reflection speed here. Anyway, we will see how it is progressing, and hopefully, we will be able to keep our Roadmap promise (halve the startup time) by the end of 2011.

Please give us your feedback!

16 comment(s)
Nate Laff

"I think that would be paradise to manage and deploy for developers."

That would be fantastic!

Looking forward to trying it out -- though, I have to be honest -- my XAF app starts pretty fast as it is. Will be insteresting to see what these improvements do for it!

28 April, 2011
James Zhong

For large sized business applications, the application start-up time is important. Thanks for your continuous XAF performance optimization!

28 April, 2011
Martin Praxmarer - DevExpress MVP

Any Infos Dennis how much we will gain with the new way in the modules?

29 April, 2011
Dennis (DevExpress Support)

@Noxe:

You will be able to gain ~ 1 second if for instance ~ 20 modules are used in your application.

29 April, 2011
Alexander Krakhotko (Xafari team)

I could not found in the file "ModulesVersionInfo" image space plane:)

29 April, 2011
Dennis (DevExpress Support)

@Alexander:

LOL!

I have just checked the source code and see that this space plane comes as bonus for licensed users only;-)

29 April, 2011
Dennis (DevExpress Support)

@Nate: We will be eager to hear your results once 11.1 is out!

@James: Thank you for the feedback. You are always welcome!

29 April, 2011
Arjan van Dijk

Can NGEN help here?

29 April, 2011
Dennis (DevExpress Support)

@Arjan:

Sure, it can. And I remember that some XAF customers used this approach.

See also:

connect.microsoft.com/.../ViewFeedback.aspx

29 April, 2011
Nate Laff

Oh yeah -- something else. Are these new files generated in the assembly directory, or in the UserModelDifferencesPath?

I install to program files, which, if new files are being created, would mean they would need admin priviledges in Vista/7... which would be bad. So hopefully they're in the UserModelDifferencesPath :)

29 April, 2011
Dennis (DevExpress Support)

@Nate: It is possible to change the default path by overriding the GetDcAssemblyFilePath, GetModelAssemblyFilePath and GetModulesVersionInfoFilePath methods. So, it is not a problem at all.

29 April, 2011
Nate Laff

Thanks Dennis! You guys are on top of everything it seems!

29 April, 2011
Dennis (DevExpress Support)

;-)

29 April, 2011
Marco

This is breaking news. Awesome!

I noticed that the loading of types is currently single-threaded. Maybe it's an idea to make this multithreaded to improve performance even further, now we (almost) don't have singlecore machines anymore?

29 April, 2011
Robert Fuchs

@Dennis, can you please explain what you mean with "gain 1 second"?

Is this a typo?

I mean - 1 second - seriously?

This is nothing compared to the huge XAF startup time.

eg. 20 secs or 19 secs - who cares?

2 May, 2011
Dennis (DevExpress Support)

@Robert: No, there is no type here.

@Marco: Thank you for the suggestion. It is also a possible solution, but it may be undesired in some scenarios, because if all the processors will be busy with a single task other applications may become unresponsible. In any case, we will consider this option for the future.

3 May, 2011

Please login or register to post comments.