Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MUXC's XamlMedataProvider::GetXamlTypeByFullName() causes serious increase in app startup time when the number of xaml controls increase #8281

Closed
ujjwalchadha opened this issue Mar 14, 2023 · 4 comments
Labels
area-Performance area-XamlCompiler bug Something isn't working product-winui3 WinUI 3 issues team-Controls Issue for the Controls team team-Markup Issue for the Markup team
Milestone

Comments

@ujjwalchadha
Copy link

ujjwalchadha commented Mar 14, 2023

Describe the bug

Adding a WinUI library which has a lot of controls (like "CommunityToolkit.WinUI.UI.Controls" Version "7.1.2" ) increases our app startup time to a massive 2 minutes 20 seconds!

Some initial investigation on the etl traces shows the methods GetXamlTypeByFullName taking 112 seconds and GetXamlType taking 17 seconds!

At first glance it seems like there are a lot of redundant recursive calls happening (looking for the same providers multiple times and doing a lot of linear scans in each of those recursive calls. An optimized version of this method can probably give a big perf win.

I would be willing to share etl traces from my machine for further investigation.

Steps to reproduce the bug

  1. Create a windows app sdk app
  2. Add a reference to any winui library with a lot of controls (like "CommunityToolkit.WinUI.UI.Controls" Version "7.1.2")
  3. Use a type in xaml (like CommunityToolkit.WinUI.UI.Controls.AdaptiveGridView)
  4. Measure app startup time

Expected behavior

App startup is fast

Actual behavior

App startup is in minutes (mostly spent in xaml parsing)

Screenshots

No response

NuGet package version

WinUI 3 - Windows App SDK 1.2.4: 1.2.230217.4

Windows version

Windows Insider Build (xxxxx)

Additional context

No response

@ujjwalchadha ujjwalchadha added the bug Something isn't working label Mar 14, 2023
@evelynwu-msft evelynwu-msft changed the title GetXamlTypeByFullName causes serious increase in app startup time when the number of xaml controls increase MUXC's XamlMedataProvider::GetXamlTypeByFullName() causes serious increase in app startup time when the number of xaml controls increase Mar 28, 2023
@evelynwu-msft evelynwu-msft added team-Controls Issue for the Controls team team-Markup Issue for the Markup team labels Mar 28, 2023
@evelynwu-msft
Copy link
Contributor

evelynwu-msft commented Mar 28, 2023

There are a few factors in play that are interacting with each other in a suboptimal fashion.

  1. Each generated IXamlMetadataProvider has an OtherProviders collection property that allows it to query referenced libraries' own IXMPs for the requested type. Providers in this property are not single-instanced. So if you have a complex app that uses lots of different WinUI control libraries then you could end up with a large (and potentially exponential) number of instances of the same fundamental IXMP. (For reference, Ujjwal's app without his change change has 491 instances of MUXC's IXMP. Adding the single Nuget package reference skyrockets that count to 1428.)
  2. Exacerbating the above is a bug in MUXC's IXMP implementation. Specifically, every time an instance is created it re-registers all of its known types. The overhead, both CPU and memory, from this can easily become non-negligible (a few hundred structs are getting appended to a std::vector each time). This also impacts the time required to return a negative result: that vector (which has several hundred thousand entries in Ujjwal's repro) needs to be exhaustively searched the first time the app encounters a type name (the code generated by XamlCompiler caches returned type information). In a worst case scenario, the app may end up searching that std::vector hundreds of times before it finally finds the requested type information.
  3. As an optimization, MUXC's IXMP (and the IXMP generated by XamlCompiler) could return early if it is asked for a type that doesn't belong to any of its known namespaces.

@evelynwu-msft evelynwu-msft added the product-winui3 WinUI 3 issues label Mar 28, 2023
@evelynwu-msft evelynwu-msft added the fixed-internally This bug has been fixed, and the fix will be shipped in the next version of WinUI 3. label Apr 27, 2023
@asklar
Copy link
Member

asklar commented Apr 29, 2023

thank you @ujjwalchadha, @evelynwu-msft, @manodasanW and @florelis for the great work on this!

@evelynwu-msft
Copy link
Contributor

https://task.ms/44125029

@bpulliam bpulliam added this to the WinUI 3 in WinAppSDK 1.3 milestone May 12, 2023
@bpulliam bpulliam added fixed-in-WinAppSDK1.3 and removed fixed-internally This bug has been fixed, and the fix will be shipped in the next version of WinUI 3. labels Jun 14, 2023
@bpulliam
Copy link
Contributor

Fixed in 1.3.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Performance area-XamlCompiler bug Something isn't working product-winui3 WinUI 3 issues team-Controls Issue for the Controls team team-Markup Issue for the Markup team
Projects
None yet
Development

No branches or pull requests

4 participants