Conversation
fix symbol logic resolution to avoid looping too much building the Xaml.UnitTests, sourcegen times Oct 27: 24,163s Oct 29: 16,139s (#32242) today : 1,363s That's a speedup of 95%, and it now takes less time so tourcegen than to XamlC
1fdf44e to
93ccbe0
Compare
There was a problem hiding this comment.
Pull Request Overview
This PR refactors the XAML source generator to improve performance by:
- Renaming
AssemblyCachestoAssemblyAttributesfor better clarity - Adding a type resolution cache to avoid redundant type lookups
- Implementing a direct namespace-to-CLR mapping dictionary for faster type resolution
- Replacing complex type resolution logic with a simpler, more efficient approach
- Removing unused extension methods and dead code
Reviewed Changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Controls/tests/Xaml.Benchmarks/Program.cs | Updates benchmark runner to use BenchmarkSwitcher for more flexible benchmark execution |
| src/Controls/src/Xaml/XmlnsHelper.cs | Removes redundant null assignment that was duplicated in ParseXmlns method |
| src/Controls/src/Xaml/XamlParser.cs | Wraps runtime-specific extension methods with #if !__SOURCEGEN__ to exclude them from source generator compilation |
| src/Controls/src/SourceGen/XmlTypeExtensions.cs | Implements caching and optimized type resolution with pre-computed CLR namespace mappings |
| src/Controls/src/SourceGen/Controls.SourceGen.csproj | Removes unused XmlTypeXamlExtensions.cs file reference |
| src/Controls/src/SourceGen/AssemblyAttributes.cs | Renames class from AssemblyCaches to AssemblyAttributes and adds ClrNamespacesForXmlns dictionary |
| src/Controls/src/SourceGen/GeneratorHelpers.cs | Updates to use AssemblyAttributes, adds ClrNamespacesForXmlns dictionary population, changes SingleOrDefault to FirstOrDefault, removes unnecessary braces |
| src/Controls/src/SourceGen/*.cs (multiple) | Updates all references from AssemblyCaches to AssemblyAttributes |
|
|
||
| var extsuffixes = (name != "DataTemplate" && !name.EndsWith("Extension", StringComparison.Ordinal)) ? new [] {"Extension", string.Empty} : [string.Empty]; | ||
| foreach (var suffix in extsuffixes) | ||
| { |
There was a problem hiding this comment.
Inconsistent indentation: the opening brace uses spaces instead of tabs. The codebase uses tabs for indentation.
| { | |
| { |
| return true; | ||
| } | ||
| } | ||
| symbol = null; |
There was a problem hiding this comment.
Inconsistent indentation: the closing brace uses spaces instead of tabs. The codebase uses tabs for indentation.
| symbol = null; | |
| symbol = null; |
| var typeArguments = xmlType.TypeArguments.Select(typeArg => typeArg.GetTypeSymbol(reportDiagnostic, compilation, xmlnsCache)!).ToArray(); | ||
| symbol = symbol.Construct(typeArguments); | ||
| XmlnsHelper.ParseXmlns(xmlType.NamespaceUri, out _, out var ns, out _, out _); | ||
| namespaces = [ns!]; |
There was a problem hiding this comment.
Using null-forgiving operator (!) on ns after ParseXmlns could cause a NullReferenceException if ParseXmlns doesn't initialize ns. Since ParseXmlns now lacks initialization at line 21, callers may pass uninitialized values. Consider adding null check: if (ns is null) { symbol = null; return false; }
| namespaces = [ns!]; | |
| if (ns is null) | |
| { | |
| symbol = null; | |
| return false; | |
| } | |
| namespaces = [ns]; |
|
/azp run MAUI-UITests-public |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Description of Change
fix symbol logic resolution to avoid looping too much
building the Xaml.UnitTests, sourcegen times
Oct 27: 24,163s
Oct 29: 16,139s (#32242)
today : 1,363s
That's a speedup of 95%, and it now takes less time to sourcegen than to XamlC