-
Notifications
You must be signed in to change notification settings - Fork 124
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
Cythonize the call loop #263
base: main
Are you sure you want to change the base?
Conversation
Ahh yeah so there's an import cycle in this.. I need to break out the It's that or we move the |
sounds fair |
One other idea: given the Might just make sense to actually play with writing properly tuned cython code to see if there's any benefit before jumping on that wagon tho. |
I proposed this before in #227 so 👍 from me |
I have been working a bit on pytest performance lately, so let me know once you believe that the implementation is semantically correct, and I'll do some profiling on pytest (when I get the chance). |
@bluetech sounds good! I'm just gonna put up a PR to split out the |
4ad5d08
to
d61800d
Compare
I rebased this onto #268 so once that's merged I'll rebase onto |
888f975
to
7e3d794
Compare
try: # run impl and wrapper setup functions in a loop | ||
teardowns = [] | ||
try: | ||
for hook_impl in reversed(hook_impls): |
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 wonder if there is a way to line up implementations better so we cna do less work and less work on calls,
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.
@RonnyPfannschmidt oh there definitely is. I actually have some ideas but it's going to require some rejigging of how implementations are stored/managed in the manger iirc and I think this may have something to do with the way we couple tracing to that management (see #262 and #217). I also think we should let @bluetech play with it in the context of pytest
before we get too ahead of ourselves - micro-benchmarks shouldn't be our guiding light IMO.
I also thought about this a while back with ideas for the rework of internals.. let's see if I can find some notes.
@RonnyPfannschmidt another question I have is how to implement both of these implementations (cython and python) without too much duplicate work.
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.
@goodboy as cython has a python mode, where a annotated file is next to the implementation file, i beleive we can do it better these days (by implementing it in python, and then cythonizing those files
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.
So then it is as simple as running cython on the original code?
Haven't looked at cython in ages.
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.
im going to sprint on this next week, i hope to get a sync with simon from datasette about async use of pluggy before so we can enable that as well
Cythonize `pluggy.callers._multicall` which gives around a 2x speedup according to the benchmark suite. Transform the `pluggy.callers` module in a new package and move utils and the legacy call loop into separate modules.
When cython is installed always rebuild the C sources, when not installed use whatever C sources were included in the sdist.
This reverts commit 72948af since we need this parametrization for testing the cythonized version of `_multicall` aka `pluggy.caller.cythonized._c_multicall()`.
7e3d794
to
f5d4eb4
Compare
Running pytest's test suite against this branch (+ switching to _c_multicall) gives two failures:
Details
I haven't looked at them, might be just something on pytest's side. And here is a small pytest benchmark that I've used recently, which is not egrigously micro-benchmarky: import pytest
@pytest.mark.parametrize("x", range(5000))
def test_foo(x): pass it fires 100,408 hooks (I think). I run it under cProfile (best of 5, output is trimmed at 1s cumtime): ResultsBefore:
After:
So it's a 5% improvement. Note that cProfile slows down the total execution time but relatively it should be about right. IMO, 5% is probably not enough to be worth it, given that Cython, C extensions, wheels etc. are a huge headache all around. But if the Cython implementation can be sped up further I'll be happy to check again. |
Yeah nothing to write home about.
Agreed, at least not as the default packaging. I think that if we want to include it as an optional dependency once we can get a better speedup that's something to consider. |
What's the raw execution time on cryptography for example, or a test suite with 40k tests |
@goodboy mypyc cant do pluggy ^^ - i tried it before ^^ |
Resolves #104 and is something I wrote a few years ago after a discussion with @RonnyPfannschmidt.
I haven't integrated the
_c_multicall()
into the benchmark tests yet (starting to think I shouldn't have removed the multiple loops from #147 🙄) but this is at least a draft that builds the faster function.Update: Above is all complete.
Interested to see what peeps think!
TODO:
cython
an optional dependency?