python / python/cpython

Optimize int add/sub for wide exact ints

未關閉
#151,289 6 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

interpreter-core performance type-feature
主要語言
Python
星號
77.2k
分支
36k
PR 合併指標
PR 指標待擷取

描述

CPython has a fast path for compact integers in binary add/sub, but wide exact ints still go through the generic long arithmetic path even when both operands fit in int64_t.

This issue proposes adding a separate fast path for exact PyLong operands that fit in signed 64-bit integers, while preserving the existing compact-int path.

Suggested implementation:

  • Keep the current compact-int specialization unchanged.
  • Add a separate wide-int path for exact ints that fit in int64_t.
  • Preserve current behavior for overflow, subclasses, and other non-exact-int cases.

Motivation:

  • Improve performance for wide integer add/sub without affecting the common compact-int hot path.
  • Avoid adding new opcodes in the compact-int path.
  • Fit within the current interpreter and specialization structure.

Benchmark evidence:

  • I prototyped this locally with a benchmark covering compact and wide add/sub cases.
  • Wide cases improved substantially, while compact cases remained effectively flat.
  • Representative interpreter-only results with JIT disabled:
    • add_wide: about 25% faster
    • sub_wide: about 35% faster
    • add_compact/sub_compact: effectively unchanged

Benchmark script used locally:

"""Microbenchmark compact vs wide int add/sub with pyperf.

Use this with PYTHON_JIT=0 and -S if you want a stable interpreter-only run:

    PYTHON_JIT=0 ./python.exe -S Tools/scripts/bench_wide_int_pyperf.py
"""

from __future__ import annotations

import pyperf


def bench_add_compact() -> int:
    a = 1
    b = 2
    return a + b


def bench_add_wide() -> int:
    a = 10_000_000_000
    b = 1
    return a + b


def bench_sub_compact() -> int:
    a = 1
    b = 2
    return a - b


def bench_sub_wide() -> int:
    a = 10_000_000_000
    b = 1
    return a - b


def main() -> None:
    runner = pyperf.Runner()
    runner.bench_func("add_compact", bench_add_compact)
    runner.bench_func("add_wide", bench_add_wide)
    runner.bench_func("sub_compact", bench_sub_compact)
    runner.bench_func("sub_wide", bench_sub_wide)


if __name__ == "__main__":
    main()
Linked PRs
  • gh-151290

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

先檢視連結的 PR gh-151290,接著檢查 issue 中描述的直譯器特化結構。使用 PYTHON_JIT=0 和 -S 執行 Tools/scripts/bench_wide_int_pyperf.py,以比較 compact 和 wide 的 add/sub 情況。完成的標準是:相容於 int64 的 wide 運算元使用 fast path,同時 compact、overflow、subclass 和 non-exact-int 的行為維持不變。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
performance
Issue 類型
重構
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
25/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。