Plasma-emojier is very slow / makeQtWrapper is accidentally quadratic?

Plasma’s emoji picker (M-.) is pretty slow for me (half a second to startup).

I reported the issue upstream:

https://bugs.kde.org/show_bug.cgi?id=468328

But, after short investigation, it seems that the problem might be on the Nix side actually? Profiing the startup shows that a lot time is spent in the following stack trace:

parameter_brace_remove_pattern
param_expand
expand_word_internal
expand_string_assignment
expand_string_if_necessary
do_assignment_internal
do_assignment_statements.isra.0
expand_words
execute_command_internal.localalias
execute_command
reader_loop
main
__libc_start_call_main
__libc_start_main_alias_2
_start

which looks like shell expansion to me.

And looking at the wrapper script for emojier, it is not that surprising that some string manipulation takes a lot of time:

It seems that that’s accidentally quadratic? Is this a know issue?

Can you try if using makeBinaryWrapper makes a noticable difference?

1 Like

filed an issue for this: wrap-qt-apps-hooks leads to very slow wrapper scripts · Issue #225871 · NixOS/nixpkgs · GitHub

Still rebuilding the world to check if that’d break, but, from what I can tell, it wouldn’t help. makeBinaryWrapper has the same quadratic behavior for repeated --prefix arguments:

Look at this! It actually does fix the issue! I believe it is still O(N^2), but the actual runtime is only 5ms. That’s surprising, I would’ve expect bash to do more or less what the C code does anyway.

1 Like

https://github.com/NixOS/nixpkgs/pull/225881

WoW :slight_smile: nice ! THANK YOU!

I am “afraid” to try this, as it rebuilds webengine… (any way to disable qtwebengine from plasma??)

I have noticed (very much, since I do it all the time) also that launching apps through shortcuts also feels slow (ex: starting konsole through plasma keyboard shortcut feels slower than just clicking on icon or launching from terminal )… hope this fixes it :slight_smile:

That seems like it is a different issue: the wrapper being slow should affect both use cases equally.

You can experiment with this locally by running

$ cat $(which konsole) | head -n -1 > wrapper.sh
$ chmod a+x wrapper.sh
$ time wrapper.sh
$ time konsole -h

This should allow you to check which fraction of konsole’s startup is accounted for by the wrapper.

I don’t know a good way to check global shortcuts latency, but, as an anecdotal evidence, they certainly seem instant to me.

Ohh … thanks for the input… then it must be another issue.

Its not like the global shortcuts are slow, but that 100ms you mentioned, that seemed it.

I notice it from switching from gentoo or arch, but its not something like 10 seconds or something that is easy to catch and show.

Anyway…
As a test, what I did was, using your wrapper.sh, opened a bash session which I sourced the env from wrapper.sh.

Then I launched .konsole-wrapped (with full path) directly, and benchmarked it with hyperfine.
Then did the same for using normal konsole bin (with full path).

EDITED: It seems the wrapper.sh is reponsable here for about 50~60ms. (I also hyperfined wrapper.sh directly, which showed more or less the same time).

Okey, turns out that is totally an issue:

https://bugs.kde.org/show_bug.cgi?id=468440

The reason why it feels snappy for me is that I don’t use global application shortcuts (which are slow), but rather pin apps in taskbar and use Win+1, Win+2, etc (which are surprisingly faster).

2 Likes

Awesome work !!!

Strangelly, I only notice it on nixos… maybe its the adding on of little 10ms here, 50ms there, etc.

Thank you very much for your help !

@matklad

saw your reply on kde bug report, doesn’t kstart take 330ms because it segfaults at the end?

i get around that same time because of the segfault at the end, i think. ( I get 40ms in gentoo, and around 80ms in arch )

( btw a good test to check between using meta+1/2/3/etc and kglobalaccell, is just shimming kstart and put a sleep 1 or 2 seconds before calling the real kstart. the meta+1/2/3/etc aren’t affected, but normal shortcuts are )

EDIT: clarification, seems the segfault only happens when kstart --help for example, not when running a valid command, so I guess the question above is answered

Final log …

So now that this fix is in, it went from previously (using kstart as an example, which is called on kglobalshortcuts for now):

[::: /home/alex :::]: hyperfine 'kstart -- bash -c exit'                                                                                             [::: 🛡 Sistema 🛡 :::]
Benchmark 1: kstart -- bash -c exit
Time (mean ± σ):     196.2 ms ±   2.2 ms    [User: 155.9 ms, System: 39.1 ms]
Range (min … max):   193.0 ms … 200.3 ms    14 runs

to

[::: /home/alex :::]: hyperfine 'kstart -- bash -c exit'                                                                                             [::: 🛡 Sistema 🛡 :::]
Benchmark 1: kstart -- bash -c exit
Time (mean ± σ):     118.4 ms ±   1.5 ms    [User: 80.1 ms, System: 38.2 ms]
Range (min … max):   116.4 ms … 122.0 ms    24 runs

Coming back here later, it feels like plasma apps still sometimes are way too slow to start.

Eg, that’s what I get now:

$ t plasma-emojier --version
plasma.emojier 5.27.9

real 2.03s
cpu  1.72s (122.97ms user + 1.59s sys)
rss  116.19mb

$ t plasma-emojier --version
plasma.emojier 5.27.9

real 207.18ms
cpu  199.30ms (115.92ms user + 83.38ms sys)
rss  116.34mb

That is, the first time around starting up an app can take up to 2 seconds, which is not reasonable at all. Haven’t debugged this one yet.

sort-of debugged maybe?

That’s the slow syscall:

23:43:01 ioctl(14, _IOC(_IOC_READ|_IOC_WRITE, 0x46, 0x2b, 0x20), 0x7fff648c1e40) = 0 <1.818853>

Apparently this has something to do with my nvidia video card, and it looks like what’s happening is that GPU driver is being unloaded:

(this is mostly a guess at this point, but the theory looks sound).

Not sure what’s the problem though – the fact that the driver is unloaded, or the fact plasma emojier needs to poke nvidia driver at all…