python / python/cpython

Constant-fold f-strings with constant fields in the CFG optimizer

Đang mở
#154,910 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

interpreter-core performance type-feature
Ngôn ngữ chính
Python
Star
77.2k
Fork
35.9k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

Feature or enhancement

Proposal:

The flowgraph optimizer folds constant expressions in most positions (binary/unary ops, tuples of constants, in against literal collections), but f-strings whose fields are all constants are left unfolded:

>>> import dis
>>> dis.dis(lambda: f'{1}{2}')
   RESUME                   0
   LOAD_SMALL_INT           1
   FORMAT_SIMPLE
   LOAD_SMALL_INT           2
   FORMAT_SIMPLE
   BUILD_STRING             2
   RETURN_VALUE

This could compile to a single LOAD_CONST '12', the same way '1' + '2' already does.

The transformation is safe under a narrow guard:

  • FORMAT_SIMPLE on an operand that is an exact str, int, float or bool constant is pure and calls no user code (subclasses can override __format__/__str__, so exact-type checks are required).
  • FORMAT_WITH_SPEC with a constant spec on those exact types is pure for the same reason, though it could be left to a follow-up.
  • BUILD_STRING over constant strings is pure.

Conversion functions (!r, !s, !a) lower to intrinsics before FORMAT_SIMPLE, so f'{1!r}' is out of scope unless the intrinsic is also handled; the initial change can simply not match those sequences.

Constant fields do appear in real code — mixed f-strings like f'{HEADER}{x}' gain partially (the constant fields fold, shrinking BUILD_STRING's operand count), and fully-constant f-strings show up in generated code and in string-building via comprehensions.

The natural place is a fold_format_simple alongside fold_tuple_of_constants in Python/flowgraph.c, using the existing get_const_loading_instrs / instr_make_load_const helpers.

gh-77273 covered the opcode-level inefficiency of f-string formatting and was resolved by the FORMAT_SIMPLE/FORMAT_WITH_SPEC redesign; this proposal is about folding the constant cases of those opcodes, which is not currently done anywhere in the compiler.

With a prototype of the fold, a fully-constant f-string costs the same as the equivalent string literal (~34 ns/call instead of ~1770 ns/call on a debug free-threaded build — I'll post release-build pyperf numbers on the PR). I have a patch ready and will follow up with it.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs
  • gh-154911

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu trong Python/flowgraph.c, bên cạnh fold_tuple_of_constants, và xem lại get_const_loading_instrs cùng instr_make_load_const. Xác minh rằng trình tối ưu hóa xử lý các chuỗi FORMAT_SIMPLE và BUILD_STRING hằng đủ điều kiện, đồng thời giữ nguyên các phép chuyển đổi và các kiểu không chính xác tuyệt đối, sau đó so sánh bytecode được tạo ra và hiệu năng với PR được liên kết gh-154911.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
python
Lĩnh vực
compilers
Loại issue
Tính năng
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
25/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.