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

Initial display of templated controls is slow #1529

Closed
ahopper opened this issue Apr 28, 2018 · 18 comments
Closed

Initial display of templated controls is slow #1529

ahopper opened this issue Apr 28, 2018 · 18 comments

Comments

@ahopper
Copy link
Contributor

ahopper commented Apr 28, 2018

I have a dialog with 140 checkboxes (not as silly as it might sound, they set hardware outputs), on first display it takes a couple of seconds. Simplifying the checkbox template reduces it to about 0.5 sec, this still looks bad in my app as the live graphical background freezes. Profiling indicates the time is spent in TemplatedControl.ApplyTemplate that is called by Measure. If the checkbox template is reduced to just a Border it still takes approx 20 times as long as showing 140 borders directly.
Is anything planned to improve this like compiling xaml or some other code generation of template factories?
I did wonder if in this case the template construction could be cached and cloned as the same template is used repeatedly, my initial attempts have failed.

@ahopper
Copy link
Contributor Author

ahopper commented Apr 29, 2018

this is possibly the same (or related to) #1394 I initially saw the problem in an ItemsControl but it was still slow after creating the content manually outside the ItemsControl.

@Gillibald
Copy link
Contributor

Maybe we can introduce some kind of factory in the future for templates combined with some code generation we can speed up loading times.

Just tested a small scenario with a collection of 100 items and a trivial data template and got poor results with default virtualization.

@ahopper
Copy link
Contributor Author

ahopper commented Apr 30, 2018

Yep some code generation of template and style factories should be faster than all the reflection used at the moment, I asked the question to see if there was something grand in the pipeline before trying to tackle it by tweaking the current solution. In profiling a bit further I suspect the delays are in more than one place, a lot happens when a template is applied and I don't yet have a good enough understanding to spot if unnecessary stuff is being called. I did spot this

public AvaloniaProperty FindRegistered(Type type, string name)
is slow and could easily be sped up but that only accounts for a small part of the time.

@grokys
Copy link
Member

grokys commented Apr 30, 2018

Hmm, we can already actually create control templates in code if need be: https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Controls/Templates/FuncControlTemplate%602.cs

I wonder if using a FuncControlTemplate for the CheckBox in your case improves things?

@ahopper
Copy link
Contributor Author

ahopper commented Apr 30, 2018

Thanks, I'll have a look at that. In my attempts at profiling the issue, the call tree on applying a template is so large that if you have not got a deep understanding(ie the orig dev) of what it is trying/meant to do it is hard to spot if something is going wrong at a high level, which is where big perf gains are most easily made. So far I can see things that can be tweaked but nothing to give the order of magnitude gains that would be nice.

@grokys
Copy link
Member

grokys commented May 1, 2018

I guess it's quite possible that although Portable.Xaml was recently optimized, the code-paths for creating controls from templates weren't optimized.

As a note: in general I'd be careful about assuming final performance of Avalonia from its current performance - we haven't really started thinking about performance yet so there's that lot that can be done to improve things.

@grokys
Copy link
Member

grokys commented Jun 23, 2018

@ahopper could you try #1690 and see if it improves things for you?

@ahopper
Copy link
Contributor Author

ahopper commented Jun 23, 2018

@grokys will do, this looks very promising and covers off a significant hot spot I saw in profiling.

@ahopper
Copy link
Contributor Author

ahopper commented Jun 24, 2018

@grokys I have a test page with 400 checkboxes that I have been using for profiling, #1690 speeds it up from 3s to 1.7s for initial display so a great improvement. I had a quick go at indexing the styles by target type where possible to reduce trying every style for every element, this gave a .4s improvement so is worth further thought.

@grokys
Copy link
Member

grokys commented Mar 5, 2020

I wonder how this is looking these days? We've done quite a few perf work since this was last tested I think.

@ahopper
Copy link
Contributor Author

ahopper commented Mar 5, 2020

Yep there has been great improvement 👍 , I'll benchmark from when I raised this to now just for fun. Perf is a bit of an open ended thing so not sure whether to close, I still crave for more speed, especially on lower powered platforms.

@ahopper
Copy link
Contributor Author

ahopper commented Mar 5, 2020

I wonder if we could have some sort of ci perf benchmarks to rate prs and catch perf regressions, I guess it is tricky to do as the speed of the ci machine is not constant, I've not researched this so maybe this is a solved problem. My kpis would be times of program startup, initial control creation and repeated binding updates.

@ahopper
Copy link
Contributor Author

ahopper commented Mar 7, 2020

crude benchmark of showing 400 check boxes, the second figure is for showing a second one.

0.6.0 1665ms 1500ms - edited
0.7.0 1068ms 750ms
0.8.0 1088ms 670ms
0.9.0 500ms 290ms
0.9.999-cibuild0006235-beta 480ms 231ms

@ahopper
Copy link
Contributor Author

ahopper commented Mar 8, 2020

Interestingly showing a single CheckBox is at least 10 to 20 times faster on the second time (probably more but lost in the noise of my crude benchmark). Once a single checkbox has been shown the first showing of 400 is almost as fast as the second. I've also noticed clearing 400 CheckBoxes takes approx 35% of the time it took to display them so there are gains to be had there as it is all part of the time taken to change views.

@kekekeks
Copy link
Member

kekekeks commented Mar 8, 2020

That probably happens because JIT needs to actually compile MSIL generated by the XAML compiler. You should be able to strip more time by using R2R.

@ahopper
Copy link
Contributor Author

ahopper commented Mar 8, 2020

ReadyToRun does approx halve the time for the first single CheckBox so that is certainly part of it, and useful to know.

@kekekeks
Copy link
Member

kekekeks commented Mar 8, 2020

@grokys we should probably recommend using R2R in the docs.

@ahopper
Copy link
Contributor Author

ahopper commented Jan 6, 2023

closing as no longer a big issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants