Optimize collection literals with leading null unpack idiom in bytecode, allows bare `BUILD_SET 0`
Chưa có ai nhận issue này.
- 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:
Performance was discussed at various times within PEP 802 topic, submitting this proposal as the PEP is unlikely to be accepted. This is intended as an advanced escape-hatch not overlapping with the main reasons for PEP 802.
Goal:
- Remove performance penalty of
ast.unparse(ast.Set(elts=[]))({*()}can be used in advanced cases and will not change recommended way to write empty setset()) - Remove performance penalty of incremental construction between 0-to-1/1-to-0 elements for
setandtupleliterals without special case considerations (e.g.x = *(),pre-seeded tuple literal without trailing comma pitfall) - Keep implementation simple/self-contained in bytecode generation, avoiding any AST changes to language
- Near-zero performance impact to bytecode generation (improves subsequent bytecode optimizations of target case)
Implementation examples:
- During first AST -> bytecode pass: https://github.com/python/cpython/commit/67742d92c411a93e7692f761ffeb3af75ba1ff87#diff-6d58b0ddc066ad12ebc378b62c4189335bd57c83aece11072c76fd86a78a1a4a
- During bytecode-only optimization step: https://github.com/python/cpython/commit/f857d88ef3aac90deadf438625211040e73df832#diff-3cbf15668c31488528b7ab0f903c674a0ecf550f4f53c1be6cf8cd965246c2a0
Micro-benchmark
Run on windows x64bit release build: empty_unpack_benchmark.py
Compile time
Targeted cases:
| Benchmark | Main | Flowgraph only | Codegen leading only |
|---|---|---|---|
[*()] |
1.450 ms / 1.000x | 1.393 ms / 0.961x | 1.378 ms / 0.950x |
{*()} |
1.530 ms / 1.000x | 1.488 ms / 0.973x | 1.467 ms / 0.959x |
(*(),) |
1.916 ms / 1.000x | 1.842 ms / 0.962x | 1.832 ms / 0.956x |
x = *(), |
1.139 ms / 1.000x | 1.088 ms / 0.955x | 1.055 ms / 0.927x |
xychart-beta
title "Compile targeted mean ratio vs main"
x-axis [Main, Flowgraph, Leading]
y-axis "Ratio" 0 --> 1.01
bar [1.000, 0.963, 0.948]
Control near-miss case comparisons moved less than +/-1% and are attributed to noise.
Runtime
The set() versus {*()} comparison is especially useful because it changes qualitatively across the two branches (~6.3% slower to ~29.5% faster):
| Branch | set() mean (ns) |
{*()} mean (ns) |
{*()} vs set() |
|---|---|---|---|
| Main | 54.14 | 57.53 | 1.063x |
| Flowgraph only | 53.49 | 38.01 | 0.711x |
| Codegen leading only | 55.44 | 39.00 | 0.704x |
Before this change, {*()} was paying for a redundant empty update and ended up slower than the constructor call. After the change, {*()} compiles down to a direct BUILD_SET 0; RETURN_VALUE path, while set() still has to load the global and perform a zero-argument call.
Has this already been discussed elsewhere?
I have already discussed this feature proposal on Discourse
Links to previous discussion of this feature:
https://discuss.python.org/t/pep-802-display-syntax-for-the-empty-set/101676/237
https://discuss.python.org/t/pep-802-display-syntax-for-the-empty-set/101676/216
https://discuss.python.org/t/pep-802-display-syntax-for-the-empty-set/101676/3
Linked PRs
- gh-150812
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu bằng việc xem xét empty_unpack_benchmark.py và các ví dụ triển khai được liên kết trong đề xuất, sau đó kiểm tra PR gh-150812 được liên kết và cuộc thảo luận liên quan trên Discourse. Công việc được xem là hoàn tất khi các trường hợp collection-literal được đề xuất tránh các cập nhật rỗng dư thừa trong khi vẫn duy trì hành vi được ghi nhận và những cải thiện của benchmark.
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ó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 25/100