-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Regression in startup time 0.9 -> 0.10. #5666
Comments
The difference between 0.9.12 and 0.10.0 with the default theme is pretty big. However building it in R2R mode mostly offsets the difference. We suspect that this degradation in performance was caused by #3255, which introduces a typed value store where previously we had a boxing value store. The extensive usage of generics there is causing the JIT to do more work on startup. Profiling in dotTrace using the Timeline profiler seems to bear this out: (0.9 on the left, 0.10 on the right. Note that the times here are greater as running in the profiler slows the app down significantly) Where we've shaved off 500ms in user code we've added 400ms of JIT time. Not sure why the majority of time here is showing up as Native code though. |
My next port of call was to try to work out just why the Fluent theme is so much slower. It's a much bigger more complex theme than Default of course so there would be some performance cost to be expected; however I wanted to see if I could improve startup time with this theme as this is what most people would be using. My initial profiling led me to see that we're calling https://gist.github.com/grokys/5d1a3ded2509808807b5e699f5876672 That doesn't look good. What's happening is that the first call to get a resource causes the fluent theme to get loaded which triggers all the resources in those styles to be looked up, and for each resource lookup all the XAML files in the fluent theme need to be searched. The process of loading the fluent theme takes around 0.5s in total. |
I suspect this use of generics also caused corert builds to grow significantly. The value store rather fills the output with
on a corert build |
Yes, in fact the reason I knew to look immediately at JIT time was due to a conversation in the runtimelab repository. Thing is, we started off with a boxing/reflection-based which was criticized because it was slow, caused a lot of allocations and didn't work well with CoreRT. So what do you use to replace boxing/reflection? Generics. Indeed there is a draft PR for a typed binding system (#5510) which uses generics throughout the binding chain instead of boxing. We may well have to reconsider this direction. Feels like we're in a lose-lose situation here. You push one end in and the other pops out. |
Anyway back to investigating the fluent theme... Given that looking up resources causes so many calls trying to look for each resource, my next experiment was write a tool to merge the fluent theme into a single XAML file and use that. Running with the merged fluent theme reduced our resource lookups from 50,000 to 640! 🎉 With no noticeable improvement to startup time. 😢 Seems that looping over objects and doing dictionary lookups is actually pretty fast, even if you do it a lot. Looking at the profiling information in dotMemory shows us that most of the time in building the fluent theme is unaccounted for in user code:
Which again points to the culprit being JIT. |
Given that the slowdown seems to be due to just building the styles, it seems obvious that one solution might be to load less styles. My next experiment adds a "filter" to the
The Yep, it works. Startup time for a blank window went from 1s to 0.71s (yes my computer seems to have slowed down since I did the tests in the original post) which is a +25% speedup for a blank window. Conclusion: we need to look into this more and see if we can generalize/unhackize this solution. |
will this approach be pursued further in the future? im currently try to speed up the startup time of a simple app with just a TextBox, a Slider and a Button. StopWatch started in Trace on IMX8M Mini: |
You need to use R2R. Startup time is increased mostly due to JIT. |
I already build with R2R: |
4189.2833ms is still sounds very wrong. Not sure if it's platform specific, but on m1 and intel windows I never had so bad numbers even on slower laptop. With r2r setup. |
On iMac or any other windows machine there are significant better startup times around 1 - 1.5 seconds. |
@grokys Should this one be closed now? |
Can be retested and closed after #9495 |
Describe the bug
One of our customers has made us aware of a regression in startup time between 0.9 and 0.10. Tested this on my machine and found that this is indeed the case.
I measured the startup time in a blank app by starting a
System.Diagnostics.Stopwatch
inProgram.Main
and stopping it in the main windowActivated
event. The program was compiled in a standard release build and with a ReadyToRun (R2R) deployment:Wasn't able to test 0.9 in R2R mode as the program fails to run.
I will report the results of my investigation below.
The text was updated successfully, but these errors were encountered: