python / python/cpython

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

未关闭
#136,681 10 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

performance topic-argument-clinic type-bug
主要语言
Python
星标
77.2k
派生
35.9k
PR 合并指标
PR 指标待抓取

描述

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

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 bench.py 中的 benchmark 和 pyperf 示例开始,比较 positional-only 和 positional-or-keyword 形式下的 math.isfinite(1.0)。检查 Modules/mathmodule.c 以及由 Tools/clinic/clinic.py 生成的 Argument Clinic 输出;当 C 编写的调用不再出现报告的回归,同时 benchmark 和 API 行为保持正确时,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
c, python
领域
performance
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
30/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。