-
Notifications
You must be signed in to change notification settings - Fork 13
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
fast: add emit_fast
method for 10x faster emission (without safety checks)
#331
Conversation
emit_fast
method for 10x faster emission (without safety checks)
CodSpeed Performance ReportMerging #331 will improve performances by 11.08%Comparing Summary
Benchmarks breakdown
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #331 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 21 21
Lines 2062 2076 +14
=========================================
+ Hits 2062 2076 +14 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
did you want to add some tests to make codecov more happy?
In not, then maybe add #pragma: no cov
to remove noisy reports?
raise RecursionError( | ||
f"RecursionError when " | ||
f"emitting signal {self.name!r} with args {args}" | ||
) from e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of this solution, as it sometimes produces unreadable stack trace. But I understand that it is just a copy from plain emmit
and should be fixed in both places?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please suggest a better solution. You've complained about the stack traces in the past, and I tried hard to make what I thought were useful, readable traces. I didn't know you still didn't like them, but it would be good to have some more concrete suggestions
This sounds great! Thanks a lot for all the effort! Is it an in-place upgrade or would I need to tweak any of the settings? |
You need to call |
That's it? Super cool! Will test it later today! |
I guess you can just replace the call to |
Out of curiosity, how does |
the "standard" psygnal/src/psygnal/_signal.py Lines 1230 to 1242 in d6281fc
in the interest of speed, We could add back the thread safety, at a slight cost, but even adding a conditional to check an argument (e.g. |
@beniroquai ... no there's no way to enforce that in your dependencies, since that is a pip-specific option at install time, and not related to project metadata. You can, however, tell pip to install with no_binary for a specific package at install time: PIP_NO_BINARY=psygnal pip install ImSwitch Alternatively, you can do the "decompilation" (which simply renames the compiled libraries) in your source code, next to where you subclass, though this requires write access to the psygnal files in site-packages: # somewhere in your ImSwitch code
import psygnal.utils
psygnal.utils.decompile() note: i haven't actually tried this 😂 ... so it's possible that the first run would fail... making it not a great solution ... I'd call that a short-term patch, until I have time to look closer at #330 edit: if your solution of installing from github works for you, then that's also appropriate I suppose ... but i think i'd prefer one of the above solutions |
This PR is in response to @beniroquai's #330 (comment):
Indeed, the compiled version of psygnal is roughly 5 times slower than Qt (the uncompiled version is about 6.5-7 times slower). It looks like all that slowdown comes from safety mechanisms and other "features" that may not be used in many cases, (like the ability to query the sender, etc...). So, this PR adds a stripped down
emit_fast()
method that has the following changes:check_nargs
orcheck_types
Signal.current_emitter()
Signal.sender()
emits. It will always use "immediate" mode, wherein signals emitted by
callbacks are immediately processed in a deeper emission loop.
It DOES, however, respect
paused()
andblocked()
By stripping away those less-used features, the emission is about 10x faster (making the compiled version ~2x faster than Qt). It should be used with caution, but for most simple cases, it is probably everything one needs.