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

Speed up BaseExceptionGroup.{derive,subgroup,split} by ~20% #111666

Closed
sobolevn opened this issue Nov 2, 2023 · 1 comment
Closed

Speed up BaseExceptionGroup.{derive,subgroup,split} by ~20% #111666

sobolevn opened this issue Nov 2, 2023 · 1 comment
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) performance Performance or resource usage

Comments

@sobolevn
Copy link
Member

sobolevn commented Nov 2, 2023

There's a simple change that we can make to increase the preformance of these three methods. Right now they are defined as:

cpython/Objects/exceptions.c

Lines 1491 to 1493 in f4b5588

{"derive", (PyCFunction)BaseExceptionGroup_derive, METH_VARARGS},
{"split", (PyCFunction)BaseExceptionGroup_split, METH_VARARGS},
{"subgroup", (PyCFunction)BaseExceptionGroup_subgroup, METH_VARARGS},

However, they only ever use one argument:

if (!PyArg_ParseTuple(args, "O", &excs)) {
return NULL;
}

So, it would be much faster to use METH_O instead. I did these measurements, before and after:

» pyperf timeit -s 'e = BaseExceptionGroup("Message", [ValueError(1)] * 10); i = [TypeError(2)] * 10' 'e.derive(i)'
.....................
Mean +- std dev: 353 ns +- 2 ns

» pyperf timeit -s 'e = BaseExceptionGroup("Message", [ValueError(1)] * 10); i = [TypeError(2)] * 10' 'e.derive(i)'
.....................
Mean +- std dev: 319 ns +- 4 ns
» pyperf timeit -s 'e = BaseExceptionGroup("Message", [ValueError(n) if n % 2 == 0 else TypeError(n) for n in range(100)]); f = lambda e: True' 'e.split(f)'
.....................
Mean +- std dev: 180 ns +- 1 ns

» pyperf timeit -s 'e = BaseExceptionGroup("Message", [ValueError(n) if n % 2 == 0 else TypeError(n) for n in range(100)]); f = lambda e: True' 'e.split(f)'
.....................
Mean +- std dev: 151 ns +- 1 ns
» pyperf timeit -s 'e = BaseExceptionGroup("Message", [ValueError(n) if n % 2 == 0 else TypeError(n) for n in range(100)]); f = lambda e: True' 'e.subgroup(f)'
.....................
Mean +- std dev: 153 ns +- 0 ns

» pyperf timeit -s 'e = BaseExceptionGroup("Message", [ValueError(n) if n % 2 == 0 else TypeError(n) for n in range(100)]); f = lambda e: True' 'e.subgroup(f)'
.....................
Mean +- std dev: 121 ns +- 0 ns

Linked PRs

@sobolevn sobolevn added performance Performance or resource usage interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Nov 2, 2023
@sobolevn sobolevn self-assigned this Nov 2, 2023
sobolevn added a commit to sobolevn/cpython that referenced this issue Nov 2, 2023
@hugovk
Copy link
Member

hugovk commented Nov 9, 2023

Closing because #111667 was merged, feel free to re-open if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) performance Performance or resource usage
Projects
None yet
Development

No branches or pull requests

2 participants