26. Tối ưu hóa mã byte

Tối ưu hóa mã byte là giai đoạn dọn dẹp và sàng lọc cuối cùng trước khi đối tượng mã sẵn sàng thực thi.

Các giai đoạn biên dịch trước đó quyết định ý nghĩa của chương trình và đưa ra hướng dẫn. Tối ưu hóa cố gắng làm cho các hướng dẫn đó nhỏ hơn, đơn giản hơn hoặc nhanh hơn trong khi vẫn duy trì ngữ nghĩa Python.

Ví dụ:python id="u88pli" x = 1 + 2 có thể biên dịch như thể được viết:```python id="k8v2ef" x = 3


Nhưng điu này:```python id="lbwhpl"
x = a + b
```không th gp li được vì`a`Và`b`là các giá tr thi gian chy. Kiu ca chúng có th xác định hành vi tùy ý cho`+`.

## 26.1 Vị trí trong Đường ống biên dịch

Ti ưu hóa xy ra sau hoc trong quá trình to mã byte, tùy thuc vào loi ti ưu hóa.```text id="olp5um"
source
    
tokenization
    
parsing
    
AST
    
symbol table
    
instruction generation
    
optimization
    
assembly
    
code object
```Mt s ti ưu hóa xy ra trên AST. Mt s xy ra trên biu đồ lung điu khin hoc lung lnh. Mt s xy ra sau này trong thi gian chy thông qua chuyên môn hóa.

Đừng coi ti ưu hóa ch là mt bước duy nht. CPython s dng mt s cơ chế  các lp khác nhau.

## 26.2 Tối ưu hóa phải bảo toàn ngữ nghĩa

Python rt năng động.

Điu này gii hn nhng gì CPython có th ti ưu hóa mt cách an toàn.

Ví d:```python id="wozly6"
x = 1 + 2
```An toàn để gp.

Ví d:```python id="i4bt05"
x = "a" + "b"
```An toàn để gp.

Ví d:```python id="ue1h3y"
x = a + b
```Không an toàn để gp li.

Hot động có th gi:```python id="fk1geq"
a.__add__(b)
```hoc:```python id="h80anr"
b.__radd__(a)
```Nhng phương thc đó có th chy mã Python tùy ý.

Quy tc ti ưu hóa:```text id="o2q4tx"
Only remove or precompute work when the observable behavior remains the same.
```Hành vi có th quan sát được bao gm:```text id="g5n65q"
return values
exceptions
side effects
evaluation order
name lookup behavior
attribute lookup behavior
object identity when relevant
traceback positions
debugging behavior where specified
```## 26.3 Gấp liên tục

Vic gp hng s tính toán trước các biu thc ch được to t các hng s.

Ví d:```python id="wpyjbl"
1 + 2
2 * 3
"py" + "thon"
(1, 2) + (3, 4)
```Đây có th tr thành hng s.

Ví d:```python id="8yvbyh"
def f():
    return 1 + 2
```Mã byte có th có:```text id="gjktcx"
LOAD_CONST 3
RETURN_VALUE
```còn hơn là:```text id="rs6njs"
LOAD_CONST 1
LOAD_CONST 2
BINARY_OP +
RETURN_VALUE
```Trình biên dch lưu tr giá tr gp trong`co_consts`.

## 26.4 Gấp bảo thủ

CPython tránh các biu thc gp có th quá ln hoc quá đắt ti thi đim biên dch.

Ví d:```python id="lwt9ja"
x = "a" * 10
```có th được gp li.

Nhưng s lp li quá ln s không to ra mt hng s ln trong quá trình biên dch.```python id="k9mjrp"
x = "a" * 10_000_000_000
```Mt trình biên dch thc hin vic này mt cách mù quáng s tiêu tn b nh rt ln trước khi chương trình bt đầu chy.

Ti ưu hóa phi được gii hn.

Trình ti ưu hóa ca CPython rt thiết thc. Nó tránh biến vic biên dch thành mt cuc tn công tài nguyên không mong mun.

## 26.5 Gấp Tuple và Container

Các b ch cha hng s có th được gp li.

Ví d:```python id="i0us1v"
x = (1, 2, 3)
```có th ti mt hng s tuple.

Nhưng danh sách và tp hp có th thay đổi được nên chúng thường không th tr thành hng s.```python id="g3apua"
x = [1, 2, 3]
```phi to mt danh sách mi khi chy.

Ti sao?

Mi ln thc thi cn mt đối tượng có th thay đổi mi.

Hàm này phi tr v mt đối tượng danh sách khác nhau cho mi lnh gi:```python id="ku6rt2"
def f():
    return [1, 2, 3]
```Nếu trình biên dch lưu tr mt hng s danh sách chia s, đột biến s rò r qua các lnh gi.

## 26.6 Tối ưu hóa kiểm tra tư cách thành viên

Đối vi các bài kim tra tư cách thành viên, các hng s có th thay đổi đôi khi có th được thay thế bng các hng s bt biến.

Ví d:```python id="yku3da"
def is_small(x):
    return x in {1, 2, 3}
```Ch đã đặt ch được s dng để kim tra tư cách thành viên. CPython có th thay thế nó bng`frozenset`không thay đổi.

V mt khái nim:```text id="nibldo"
LOAD_FAST x
LOAD_CONST frozenset({1, 2, 3})
CONTAINS_OP
RETURN_VALUE
```Điu này tránh vic xây dng li tp hp mi khi hàm chy.

Vic ti ưu hóa là hp l vì bn thân đối tượng đã đặt không được hin th vi mã người dùng.

## 26.7 Mã chết sau khi thoát vô điều kiện

Mt s mã s không th truy cp được sau khi thoát vô điu kin.

Ví d:```python id="oss0kd"
def f():
    return 1
    x = 2
```Nhim v không th thc hin được.

Trình biên dch có th loi b hoc b qua các chui lnh không th truy cp được.

Li thoát vô điu kin bao gm:```text id="u7yxa5"
return
raise
break
continue
```trong bi cnh lung điu khin phù hp.

Trình biên dch vn phi lưu gi thông tin dòng và chn đoán khi cn thiết. Ti ưu hóa không th t do xóa mi th nếu nó thay đổi hành vi g li hoc liên quan đến cú pháp theo nhng cách d thy.

## 26.8 Tối ưu hóa bước nhảy

Lung điu khin thường to ra các bước nhy.

Hình dng ví d:```text id="941xx7"
JUMP_FORWARD label_a

label_a:
JUMP_FORWARD label_b

label_b:
...
```Trình ti ưu hóa có th chuyn hướng bước nhy đầu tiên trc tiếp đến`label_b`.

```text id="np02i8"
JUMP_FORWARD label_b

label_b:
...
```Điu này làm gim s lượng lnh và tránh vic gi đi không cn thiết.

Ti ưu hóa bước nhy thường an toàn vì nó duy trì cùng mt đích ca lung điu khin.

## 26.9 Dọn dẹp khối cơ bản

Trình biên dch xây dng hoc s dng các khi cơ bn bên trong.

Khi cơ bn là mt chui lnh thng có mt li vào và mt li ra.

Ti ưu hóa có th loi b các khi trng, hp nht các khi lin k hoc đơn gin hóa các cnh.

Ví d:```text id="o49sgv"
block A:
    jump block B

block B:
    jump block C

block C:
    useful work
```có th tr thành:```text id="ke9fl3"
block A:
    jump block C

block C:
    useful work
```Vic dn dp này din ra trước khi lp ráp ln cui, khi các nhãn vn còn mang tính biu tượng.

## 26.10 Bảo toàn hiệu ứng ngăn xếp

Mi ti ưu hóa phi duy trì tính chính xác ca ngăn xếp.

Ví d:```text id="3fooh0"
LOAD_CONST 1
POP_TOP
```Nếu hng s được np không có tác dng ph và giá tr ca nó b loi b thì cp này có th b loi b.

Nhưng điu này:```text id="s5gd6m"
LOAD_NAME x
POP_TOP
```nói chung là không th g b được.

Đang ti`x`có th nâng cao`NameError`.

Tương t:```text id="hng0do"
LOAD_ATTR attr
POP_TOP
```có th gi tra cu thuc tính động và đưa ra các ngoi l.

Trình ti ưu hóa phi biết thao tác nào an toàn để loi b.

## 26.11 Ràng buộc thứ tự đánh giá

Th t đánh giá Python có th quan sát được.

Ví d:```python id="bp4w5f"
f() + g()

f()phải chạy trướcg().

Cho dù kết quả củaf()dường như không được sử dụng ở một số dạng chuyển đổi, cuộc gọi không thể bỏ qua hoặc sắp xếp lại.

Ví dụ:```python id="7e0ozh" items[key()] = value()


Ti ưu hóa không th x lý các biu thc Python như các biu thc toán hc thun túy.

## 26.12 Ràng buộc tra cứu tên

Tra cu tên là động.

Ví d:```python id="pipmww"
len([1, 2, 3])
```CPython thường không th thay thế điu này bng`3`.

Ti sao?

 cp độ mô-đun,`len`có th hi phc:```python id="sksxhh"
len = lambda x: 999
```Bên trong mt hàm,`len`có th gii quyết thông qua toàn cu trước ni trang.

Trình biên dch không cho rng ni dung`len`không thay đổi.

Đây là đim khác bit chính gia ti ưu hóa Python và ti ưu hóa bng các ngôn ng được liên kết tĩnh.

## 26.13 Ràng buộc tra cứu thuộc tính

Tra cu thuc tính là động.

Ví d:```python id="o09etj"
obj.x
```Điu này có th gi:```text id="jvlw4h"
__getattribute__
__getattr__
descriptors
properties
module-level __getattr__
custom metaclass logic
```Trình biên dch không th thay thế quyn truy cp thuc tính lp li bng mt giá tr được lưu trong b nh cache tr khi nó có th chng minh rng hành vi đó không thay đổi.

Chuyên môn hóa thi gian chy có th ti ưu hóa các trường hp ph biến theo cách suy đoán, nhưng điu đó được bo v bng vic kim tra thi gian chy. Ti ưu hóa thi gian biên dch vn còn thn trng.

## 26.14`assert`Tối ưu hóa`assert`các câu lệnh bị ảnh hưởng bởi chế độ tối ưu hóa.

Ví d:```python id="ixz6ew"
assert x > 0, "x must be positive"
```Thông thường biên dch đại khái là:```text id="96ihbr"
if not (x > 0):
    raise AssertionError("x must be positive")
```Khi Python chy vi tính năng ti ưu hóa được bt, chng hn như`python -O`, các câu lnh khng định s b xóa.

Điu này thay đổi hành vi có ch ý. Nó là mt phn ca chế độ ti ưu hóa tài liu ca Python.

Quy tc thc tế:```text id="w3wpdm"
Do not use assert for required runtime validation.
```S dng các ngoi l rõ ràng cho các kim tra phi luôn chy.

## 26,15`__debug__`Hằng số đặc biệt`__debug__`được gắn với chế độ tối ưu hóa.

Thông thường:```python id="erm4nr"
__debug__ == True
```Dưới`python -O`:

```python id="my7j8j"
__debug__ == False
```Trình biên dch có th ti ưu hóa các nhánh tùy thuc vào`__debug__`.

Ví d:```python id="vd8gwm"
if __debug__:
    check()
```Trong chế độ ti ưu hóa, nhánh này có th được b qua.`__debug__`là đặc bit. Tên thông thường không nhn được s đối x này.

## 26.16 Xử lý chuỗi tài liệu

Mc độ ti ưu hóa có th nh hưởng đến chui tài liu.

Ví d:```python id="prb94t"
def f():
    """Function docs."""
    return 1
```Thông thường, chui ký t đầu tiên trong thân hàm s tr thành chui doc ca hàm.

Vi s ti ưu hóa cao hơn, chng hn như`python -OO`, các chui tài liu có th b xóa.

Điu này nh hưởng đến:```python id="abqsw1"
f.__doc__
```Trình biên dch và thi gian chy x lý các chui tài liu mt cách đặc bit vì chúng được lưu tr dưới dng siêu d liu đối tượng thay vì được thc thi như các câu lnh biu thc thông thường.

## 26.17 Tối ưu hóa kiểu nhìn trộm

Các mô t cũ hơn v CPython thường đề cp đến trình ti ưu hóa l nhìn trm.

Trình ti ưu hóa l nhìn trm xem xét mt ca s hướng dn nh và thay thế các mu không hiu qu.

Ý tưởng ví d:```text id="gqvx1f"
LOAD_CONST 1
LOAD_CONST 2
BUILD_TUPLE 2
```có th tr thành:```text id="ipc5mv"
LOAD_CONST (1, 2)
```CPython hin đại đã chuyn nhiu ti ưu hóa sang AST và các giai đon hướng dn/lung điu khin thay vì ch da vào mt l nhìn trm đơn gin.

Khái nim này vn hu ích: mt s ti ưu hóa được viết li cc b trên mt mu lnh nh.

## 26.18 Tối ưu hóa cấp độ AST

Mt s ti ưu hóa d dàng hơn trước khi tn ti mã byte.

Ví d:```python id="qsilq6"
x = 1 + 2
```AST cha:```text id="nvue0h"
BinOp(Constant(1), Add, Constant(2))
```Trình ti ưu hóa AST có th thay thế nút đó bng:```text id="iz4wys"
Constant(3)
```Sau đó, vic to mã byte ch cn ti`3`.

Ti ưu hóa cp AST cho thy cu trúc cp cao, có th d dàng hơn vic tái to li ý nghĩa t mã byte.

## 26.19 Tối ưu hóa cấp độ hướng dẫn

Các ti ưu hóa khác s d dàng hơn sau khi to lnh.

Ví d:```text id="qz307a"
remove unreachable blocks
redirect jumps
merge blocks
compute final stack sizes
shorten control flow
```Ti ưu hóa cp độ hướng dn cho thy hiu ng ngăn xếp và lung điu khin thc tế.

Nó gn vi b cc mã byte cui cùng hơn.

## 26.20 Chuyên môn hóa thời gian chạy riêng biệt

CPython hin đại cũng có chuyên môn v thi gian chy.

Điu này không ging như ti ưu hóa thi gian biên dch.

Trình biên dch phát ra mã byte chung. Trong quá trình thc thi, CPython có th chuyên bit hóa các hướng dn được s dng thường xuyên.

Các thao tác ví d:```text id="4c4nxd"
LOAD_ATTR
LOAD_GLOBAL
BINARY_OP
CALL
STORE_ATTR
```Quyn truy cp thuc tính chung có th tr thành đường dn chuyên bit nhanh hơn sau khi CPython quan sát thy hành vi thi gian chy n định.

Ti ưu hóa thi gian biên dch:```text id="p7xt6t"
happens before execution
must be safe without runtime knowledge
```Chuyên môn v thi gian chy:```text id="qo5hr8"
happens during execution
uses observed runtime types and cache guards
can fall back if assumptions fail
```S tách bit này cho phép CPython ti ưu hóa mã động mà không đưa ra các gi định v thi gian biên dch không an toàn.

## 26.21 Bộ nhớ đệm nội tuyến

Chuyên môn hóa thi gian chy s dng b nh đệm ni tuyến gn các hướng dn mã byte.

V mt khái nim:```text id="yc3mav"
LOAD_ATTR name
CACHE
CACHE
```B đệm lưu tr thông tin thi gian chy như:```text id="ymdvl9"
observed type
dictionary version
descriptor information
resolved offset
specialized handler state
```Trình biên dch chun b không gian cho b đệm. Trình thông dch s đin và s dng chúng sau này.

Đây là lý do ti sao quá trình tháo g có th hin th các mc trong b đệm khi được yêu cu.

## 26.22 Tối ưu hóa và truy nguyên

Ti ưu hóa phi bo toàn các v trí ngun hu ích.

Ví d:```python id="ett31m"
x = 1 / 0
```Ngay c khi mã xung quanh được ti ưu hóa,`ZeroDivisionError`nên tr đến mt v trí ngun có ý nghĩa.

Truy nguyên da trên ánh x mã byte đến ngun.

Trình ti ưu hóa phi cp nht hoc bo tn:```text id="wtwgmh"
line information
column information
exception table ranges
instruction offsets
```Siêu d liu b hng to ra hành vi g li kém.

## 26.23 Tối ưu hóa và ngoại lệ

Mt s biu thc trông đơn gin nhưng có th gây ra ngoi l.

Ví d:```python id="k3r2bn"
1 / 0
```Trình biên dch không nên biến điu này thành mt ngoi l ti thi đim biên dch trong quá trình biên dch thông thường.

Ngoi l phi xy ra khi mã thc thi ch không phi khi mã được biên dch.

Ví d:```python id="9o0rsd"
def f():
    return 1 / 0
```Xác định`f`nên thành công. Đang gi`f()`nên tăng`ZeroDivisionError`.

Do đó, vic gp liên tc phi tránh các phép biến đổi chuyn các ngoi l t thi gian chy sang thi gian biên dch.

## 26.24 Tối ưu hóa và nhận dạng đối tượng

Nhn dng đối tượng có th được quan sát thông qua`is`.

Ví d:```python id="q46djy"
x is y
```Trình biên dch phi tránh các phép biến đổi làm thay đổi hành vi nhy cm vi danh tính.

Đối vi các hng s bt biến, CPython có th s dng li các đối tượng, chui thc tp hoc gp các hng s theo nhng cách được hành vi trin khai cho phép. Nhưng mã không nên da vào tt c các chi tiết nhn dng c định.

Ví d:```python id="7izgy0"
(1, 2) is (1, 2)
```Kết qu có th ph thuc vào các la chn biên dch và trin khai.

Ti ưu hóa phi duy trì ng nghĩa ngôn ng, trong khi mt s hành vi nhn dng cho các hng s vn được trin khai c th.

## 26.25 Tối ưu hóa và mặc định có thể thay đổi

Các giá tr mc định ca hàm được đánh giá ti thi đim định nghĩa hàm.

Ví d:```python id="er8lwd"
def f(xs=[]):
    xs.append(1)
    return xs
```Mc định danh sách là mt đối tượng thi gian chy được lưu tr trên đối tượng hàm.

Trình biên dch không th thay thế danh sách này bng danh sách mi cho mi cuc gi vì điu đó s thay đổi ng nghĩa.

Đây không phi là li ti ưu hóa. Đó là hành vi định nghĩa hàm ca Python.

Ti ưu hóa phi tôn trng khi các đối tượng được to.

## 26.26 Tối ưu hóa các hằng số có điều kiện

Điu kin không đổi có th đơn gin hóa lung điu khin.

Ví d:```python id="epgm4i"
if False:
    x = 1
else:
    x = 2
```Trình biên dch có th b qua nhánh không th truy cp được.

Tương t:```python id="c85x72"
while False:
    work()
```Cơ th không th thc hin được.

Nhưng trình ti ưu hóa phi cn thn vi siêu d liu ngun và vi các cu trúc nh hưởng đến phm vi hoc cú pháp.

Ví d:```python id="xt3ful"
if False:
    import never_loaded
```Quá trình nhp không được thc thi nhưng s hin din ca các phép gán trong các khi không th truy cp vn có th nh hưởng đến vic phân loi biến cc b vì quá trình phân tích bng ký hiu din ra trước khi ti ưu hóa.

## 26.27 Phạm vi được quyết định trước khi tối ưu hóa

Phân tích bng biu tượng s nhìn thy toàn b AST trước khi ti ưu hóa loi b mã không th truy cp được.

Ví d:```python id="udvaey"
x = 1

def f():
    if False:
        x = 2
    return x
```Điu này vn có th làm`x`địa phương đến`f`, gây ra mt hành vi cc b không b ràng buc khi`return x`thc thi.

Trình ti ưu hóa không th đơn gin xóa bài tp và sau đó phân loi li`x`mang tính toàn cc tr khi toàn b mô hình biên dch cho phép thay đổi ng nghĩa như vy.

Phân loi phm vi là mt phn ca ng nghĩa Python và xy ra trước nhiu ln ti ưu hóa.

## 26.28 Mức độ tối ưu hóa

CPython h tr mc độ ti ưu hóa.

Các chế độ ph biến:

| Chế độ | Ý nghĩa |
| ------ | ------------------------------------------------------------------- |
| bình thường | Biên dch mc định |
|`-O`| Xóa các câu lnh khng định, đặt`__debug__`ĐẾN`False` |
| `-OO`| Đồng thi xóa tài liu |

 cp độ Python:```python id="nqc269"
import sys

print(sys.flags.optimize)
```API biên dch cũng có th nhn được cài đặt ti ưu hóa.

Ví d:```python id="ea0hid"
compile("assert False", "<input>", "exec", optimize=1)
```Mc độ ti ưu hóa là mt phn ca hành vi biên dch.

## 26,29 Giới hạn tối ưu hóa thời gian biên dịch

CPython c tình tránh ti ưu hóa thi gian biên dch mnh m.

Nó thường không thc hin:```text id="g0a8os"
function inlining
global constant propagation
type-specialized compilation
loop unrolling
escape analysis
whole-program optimization
automatic vectorization
```Lý do:```text id="kgi5lw"
dynamic name lookup
dynamic attribute access
monkey patching
import-time side effects
debuggability
compile-time cost
implementation simplicity
semantic risk
```CPython thay vào đó da vào:```text id="nam80y"
simple safe compile-time optimizations
specialized C implementations of built-in types
runtime adaptive specialization
extension modules
external JIT implementations in other runtimes
```## 26.30 Khu vực nguồn CPython quan trọng

Các tp ngun quan trng bao gm:```text id="9n21ql"
Python/ast_opt.c
Python/compile.c
Python/flowgraph.c
Python/assemble.c
Python/bytecodes.c
Lib/dis.py
Lib/test/test_peepholer.py
Lib/test/test_compile.py
```Vai trò khái nim:

| Khu vc | Vai trò |
| ------------- | -------------------------------------- |
|`ast_opt.c`| Ti ưu hóa cp độ AST |
|`compile.c`| To AST theo hướng dn |
|`flowgraph.c`| Công vic biu đồ lung điu khin |
|`assemble.c`| Lp ráp mã cui cùng |
|`bytecodes.c`| Định nghĩa Opcode và h tr thi gian chy |
|`dis.py`| Kim tra mã byte |
| kim tra | Bo v hành vi ti ưu hóa |

## 26.31 Mô hình tinh thần tối thiểu

S dng mô hình này:```text id="dz2gpc"
CPython optimization is conservative.
It folds safe constants.
It simplifies some containers and membership tests.
It removes or redirects some unreachable or redundant control flow.
It respects evaluation order, exceptions, dynamic lookup, scope rules, and source positions.
Compile-time optimization differs from runtime specialization.
Runtime specialization can use observed types and guarded inline caches.
```Ti ưu hóa mã byte ci thin mã được to trong khi vn nm trong ng nghĩa động ca Python.