-
-
Notifications
You must be signed in to change notification settings - Fork 689
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
Performance issue with update of Label.text #3162
Comments
Thanks for the report. There's four possible sources of slowdown here:
Unfortunately, the profiling trace you've provided doesn't give enough detail to work out which of these is the culprit. In terms of ways to narrow this down: It's difficult to rule out (1) or (2) in isolation; however, writing a bare bones Python.net app that just updates a label will at least give you an indication of the maximum possible refresh rate. You can rule out (3) by using `my_label._impl.native.Text = "new label" to change the label. That sidesteps Toga's abstraction layer entirely, and jumps directly to the native assignment; it's not ideal as a solution, but at least points out if that's where the performance lag is. You can test (4) by modifying this line of code in the Winforms backend. If using Finally, it's also worth pointing out that your expectations here might be unreasonable. Toga isn't a game framework. If you're updating text 25 times a second... a human isn't actually reading that text. They can't. 1/25th of a second isn't enough time to read anything of significance. If you think of other examples where desktop GUIs display content, text will often have 1Hz or 2Hz refresh rates so that the content can be read, or a graphical representation (such as a progress bar) will be used. |
These timings imply a maximum of 200 text updates per second across all labels. That does seem unreasonably low. It would require deeper profiling to find the root cause, but it's also possible that this is caused by Toga running redundant layout calculations (#2938). |
200 updates a second would also point pretty hard at the 5ms delay in the event loop (1/200th of a second is 5ms). |
Thanks for your answers, I understand that toga isn't made for the usage I was willing to make out of it. Next on my list was the fact that I was facing problem with the event loop running at 25-30ms from exiting cycle to new cycle. For this issue, my hope was that triggering a Label.text change involved an immediate rendering which I would have wanted to disable, and then proceed to rendering all Labels in one go. I still think Toga is amazing and the project needs to be continued! |
I'm not entirely sure how the rendering, specifically, is handled on the backend. As I understand it, Windows is the only backend that even supports updating the rendered display mid-loop. It might be possible for things like calls down to native property setters to be deferred to once per event loop, but this would presumably require yet another intermediary layer to cache and return such values when accessed. This is something that runs the risk of becoming desynced, needs to be tested, and might or might not actually make anything faster because of the increased overhead. #2938 is a related concept; Toga's handling of layout calculations is currently synchronous and may recalculate layouts many times per event loop. (#3063 is a (currently not working) stab at reducing this to once per loop.) |
Winforms provides a SuspendLayout API that could be used to batch updates programatically. We're already using it for some very specific cases (e.g., getting an image rendition canvas).
Agreed this is related; and in the case of Winforms, that's almost exactly the sort of place where we'd need to put the SuspendLayout call. |
Describe the bug
Updating a label takes between 5-6ms per label. This is a problem for an application that has many labels and willing to have refresh rate 25Hz.
Steps to reproduce
Execution of program with
py -m my_module
.Code snipet with line_profiler:
Timer unit: 1e-07 s
Line # Hits Time Per Hit % Time Line Contents
self.top_bar_infos
defined withself.top_bar_infos = [toga.Label('...', style=Pack(flex=1)) for _ in range(4)]
, whereself
is atoga.Box
Testing by replacing to
self.infolabel.text = 'abc'
leads to the same performance hit.Expected behavior
I expect update time <1ms per label.
Screenshots
No response
Environment
Logs
No response
Additional context
Many thanks for your help in advance
Em
The text was updated successfully, but these errors were encountered: