python / python/cpython

Slow functions calls for C-coded functions, accepting positional-or-kwarg argument vs positional-only

Open
#136,681 10 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

performance topic-argument-clinic type-bug
Dominant language
Python
Stars
77.2k
Forks
35.9k
PR merge metrics
PR metrics pending

Description

Bug report

Bug description:

I don't see measurable difference on pure-Python level, e.g. for

# a.py
import pyperf

def f1(x):
    return 1

def f2(x, /):
    return 1

runner = pyperf.Runner()
runner.bench_func("f1(1)", f1, 1)
runner.bench_func("f2(1)", f2, 1)

I got on 3.13:

$ python a.py -q
f1(1): Mean +- std dev: 233 ns +- 2 ns
f2(1): Mean +- std dev: 232 ns +- 2 ns

But for functions, implemented in C, using the Argument Clinic - the difference is bigger:

$ python bench.py -q -o patch.json
isfinite(1.0): Mean +- std dev: 152 ns +- 1 ns
$ git checkout master && make -s
Checked 114 modules (35 built-in, 78 shared, 1 n/a on linux-x86_64, 0 disabled, 0 missing, 0 failed on import)
$ python bench.py -q -o ref.json
isfinite(1.0): Mean +- std dev: 136 ns +- 1 ns

Benchmark ref patch
isfinite(1.0) 136 ns 152 ns: 1.12x slower

(In the second version - the math.isfinite() accept also keyword argument x)

a patch

(run ./python Tools/clinic/clinic.py Modules/mathmodule.c !)

diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index 7c2a421dd6..e33281ac8b 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -3156,14 +3156,13 @@ math_radians_impl(PyObject *module, double x)
 math.isfinite
 
     x: double
-    /
 
 Return True if x is neither an infinity nor a NaN, and False otherwise.
 [clinic start generated code]*/
 
 static PyObject *
 math_isfinite_impl(PyObject *module, double x)
-/*[clinic end generated code: output=8ba1f396440c9901 input=46967d254812e54a]*/
+/*[clinic end generated code: output=8ba1f396440c9901 input=a47ad6e72998b81d]*/
 {
     return PyBool_FromLong((long)isfinite(x));
 }

This performance penalty affects API decisions (e.g. https://github.com/python/cpython/pull/131886) and that looks as a bug.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs
  • gh-136732
  • gh-137202

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the benchmark in bench.py and the pyperf examples, comparing math.isfinite(1.0) for the positional-only and positional-or-keyword forms. Inspect Modules/mathmodule.c and the generated Argument Clinic output from Tools/clinic/clinic.py; done means the C-coded call no longer has the reported regression while the benchmark and API behavior remain correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, python
Domain
performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.