Improve startup and runtime performance by removing XamlTypeInvoker dead code #9736
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Removes XamlTypeInvoker dead code. This code is hit when creating an instance of a non-known type from XAML/BAML. Removing this code improves both startup and runtime performance.
Known types are types in an hard-coded list that makes them more optimized by WPF. This includes types from WPF and some BCL common types (Like int, bool, string, etc). Everything else is a non-known type so things like custom controls are non-known types.
The reason this is dead code is because
DefaultCtorXamlActivator.EnsureConstructorDelegate
always returns false because of this condition here:wpf/src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Schema/XamlTypeInvoker.cs
Line 330 in e500f8e
Since the removal of CAS from .Net,
ConstructorInfo.IsSecurityCritical
always returns true andConstructorInfo.IsSecuritySafeCritical
always returns false so the the condition is always true which means that the wholeDefaultCtorXamlActivator
class doesn't do anything.Here's the .Net code for
ConstructorInfo.IsSecurityCritical
andConstructorInfo.IsSecuritySafeCritical
which always return constants:https://github.com/dotnet/runtime/blob/a349912e4f8610f39a6ac3cb73d8d4d0968ccec4/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.CoreCLR.cs#L228-L230
Benchmarks
I benchmarked a new WPF from the Visual Studio template where I added an empty class like
public class CustomLabel : Label { }
and I added this control 20 times in the XAML of the main window. This PR shaves about 30-40 ms when starting the app.There's a small cache per-type that skips some of the code so I also benchmarked a new WPF from the Visual Studio template where I added 20 empty classes like
public class CustomLabel1 : Label { }
and I added each control in the XAML of the main window. This PR shaves about 50-60 ms when starting the app.I expect more complex apps with more non-known type in XAML to have even bigger performance gain. Projects that have a ton of non-known types are third-party control vendors (Like DevExpress, Telerik, etc) because they have a ton of custom controls.
Customer Impact
Better startup and runtime performance.
Regression
No.
Testing
Local testing using sample app that hits this specific code.
Risk
Low.
Microsoft Reviewers: Open in CodeFlow