Skip to content

Commit 18632fc

Browse files
committed
gh-136681: optimize builtin calls if kwargs allowed
This is a first part, that should address #136681. With this patch there should be no overhead for function calls if it's signature allows keyword arguments. Below are micro-benchmarks for math.fmin(), when only positional arguments are allowed (as in the main) vs positional-or-keyword. The missing part is specialization for 1-arg functions, like cmath.sin(): #136681 (comment) In the main: | Benchmark | posonly-patch | posorkw-patch | |----------------------------|:-------------:|:---------------------:| | fmin(1.0, 2.0) | 169 ns | 170 ns: 1.01x slower | | fmin(1.0, 2.0) x 2 times | 913 ns | 890 ns: 1.03x faster | | fmin(1.0, 2.0) x 100 times | 14.7 us | 14.8 us: 1.01x slower | | Geometric mean | (ref) | 1.00x faster | Benchmark hidden because not significant (1): fmin(1.0, 2.0) x 10 times With the patch: | Benchmark | posonly-ref | posorkw-ref | |----------------------------|:-----------:|:---------------------:| | fmin(1.0, 2.0) | 177 ns | 199 ns: 1.12x slower | | fmin(1.0, 2.0) x 2 times | 937 ns | 980 ns: 1.05x slower | | fmin(1.0, 2.0) x 10 times | 2.08 us | 2.25 us: 1.08x slower | | fmin(1.0, 2.0) x 100 times | 14.8 us | 16.5 us: 1.12x slower | | Geometric mean | (ref) | 1.09x slower | Benchmark code: ```py import pyperf from math import fmin def f(n): for _ in range(n): fmin(1.0, 2.0) runner = pyperf.Runner() runner.bench_func('fmin(1.0, 2.0)', fmin, 1.0, 2.0) for n in [2, 10, 100]: s = f'fmin(1.0, 2.0) x {n:3} times' runner.bench_func(s, f, n) ```
1 parent d7e12a3 commit 18632fc

File tree

102 files changed

+3564
-1747
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+3564
-1747
lines changed

Include/internal/pycore_modsupport.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,6 @@ PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords(
8484
int minkw,
8585
int varpos,
8686
PyObject **buf);
87-
#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, varpos, buf) \
88-
(((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \
89-
(minpos) <= (nargs) && ((varpos) || (nargs) <= (maxpos)) && (args) != NULL) ? \
90-
(args) : \
91-
_PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \
92-
(minpos), (maxpos), (minkw), (varpos), (buf)))
9387

9488
#ifdef __cplusplus
9589
}

0 commit comments

Comments
 (0)