- Trình thông dịch tail-calling của CPython cho thấy hiệu năng nhanh hơn khoảng 15% so với cách hiện tại trong môi trường Windows x86-64
- Trên macOS AArch64 (XCode Clang), cũng ghi nhận cải thiện hiệu năng khoảng 5%, còn trên Windows thì tận dụng tính năng thử nghiệm của MSVC 2026
- Trong benchmark pyperformance, phần lớn các bài test đều cho thấy tốc độ được cải thiện, một số trường hợp tăng tối đa tới 78%
- Nguyên nhân chính của mức tăng hiệu năng được phân tích là do đặt lại heuristic tối ưu hóa của compiler và cải thiện khả năng inline
- Khi Python 3.15 phát hành chính thức, tính năng này dự kiến sẽ được áp dụng mặc định trong các bản build dựa trên Visual Studio 2026
Cải thiện hiệu năng của trình thông dịch tail-calling
- Trình thông dịch tail-calling của CPython được đo là nhanh hơn khoảng 15% so với trình thông dịch switch-case hiện có trên Windows x86-64
- Theo pyperformance, trung bình hình học tăng 15~16%
- Một số benchmark tăng tốc tối đa 78%, trong khi một số ít chậm hơn 60%
- Trên macOS AArch64 (XCode Clang), xác nhận mức cải thiện hiệu năng khoảng 5%
- Kết quả này có giá trị với giả định rằng sẽ không có thay đổi trong chu kỳ phát triển của Python 3.15
So sánh cấu trúc trình thông dịch
- Các cách triển khai trình thông dịch bằng C được chia thành ba kiểu: switch-case, computed goto và tail-call threaded
- switch-case: xử lý rẽ nhánh theo từng lệnh
- computed goto: phần mở rộng của GCC/Clang, nhảy trực tiếp tới địa chỉ rẽ nhánh
- tail-call threaded: tách mỗi handler bytecode thành một hàm riêng, rồi tail call sang hàm tiếp theo
- Trước đây, compiler C không đảm bảo tối ưu hóa tail call nên có nguy cơ tràn stack
- Với các thuộc tính
__attribute__((musttail)) của Clang và [[msvc::musttail]] của MSVC, giờ đây có thể bắt buộc tail call
Kết quả build bằng MSVC 2026 cho Windows
- Trong bản build CPython dùng tính năng thử nghiệm của MSVC, đa số benchmark đều tăng tốc
- Ví dụ kết quả:
spectralnorm: 1.48 lần
nbody: 1.35 lần
bm_django_template: 1.18 lần
xdsl: 1.14 lần
- Nội dung này đã được phản ánh chính thức trong tài liệu “What’s New” của Python 3.15
- Có thể sử dụng trình thông dịch tail-calling trong các bản build bằng Visual Studio 2026 (MSVC 18)
- Thư viện Python thuần có thể nhanh hơn khoảng 15%, còn script nhỏ có thể tăng tốc tối đa 40%
Nguyên nhân của cải thiện hiệu năng
- Tail calling khởi tạo lại heuristic tối ưu hóa của compiler, từ đó dẫn tới việc sinh mã hiệu quả hơn
- Vòng lặp trình thông dịch CPython hiện tại gồm một hàm đơn dài khoảng 12.000 dòng nên thường xuyên thất bại trong tối ưu hóa inline
- Có nhiều trường hợp compiler từ chối inline để tránh làm tăng kích thước mã
- Với cách tail calling, các hàm được tách riêng nên những hàm đơn giản có thể được inline
- Ví dụ, các hàm đơn giản như
PyStackRef_CLOSE_SPECIALIZED có thể được inline
- Hiện tượng tương tự cũng được ghi nhận trong các bản build PGO (profile-guided optimization)
Cách build và sử dụng
- Hiện tại chỉ có thể build từ mã nguồn
- Về sau, khi quá trình phát triển Python 3.15 ổn định hơn, sẽ có phân phối binary chính thức
1 bình luận
Ý kiến trên Hacker News
Đây là ví dụ cho thấy sự khác biệt trong cách định nghĩa thuộc tính
musttailvàpreserve_nonegiữa MSVC và ClangCác thuộc tính này phải được gắn vào declarator của hàm, và không hoạt động ở vị trí function specifier
Liên kết mã liên quan
Bình luận này cũng gợi cảm giác rằng Microsoft dường như chỉ tiết lộ các tính năng không công khai như vậy cho những dự án mà họ cho là quan trọng
[[msvc::musttail]]thực ra là thuộc tính đã được tài liệu hóa chính thứcTôi sẽ sửa lại bài blog để phản ánh điều đó
Bình luận HN liên quan
Sau khi đọc bài, người này cho rằng cách tiếp cận ưu tiên tính minh bạch và phản hồi nhanh là ổn
Sẽ còn tốt hơn nếu có kiểm chứng bằng cross-compiler hoặc kiểm toán độc lập, nhưng họ vẫn tin tưởng nhờ sự minh bạch hoàn toàn của tác giả
Vì được công bố sớm nên Nelson đã phát hiện bug của Clang 19, nhờ đó có thể sửa trước khi phát hành chính thức
Lần này có thêm hai cải tiến là dispatch logic và inlining, nên họ tự tin hơn
MSVC có thể biến trình thông dịch switch-case thành threaded code trong một số điều kiện nhất định, nhưng CPython quá phức tạp nên tối ưu đó không được áp dụng
Thay vào đó, cách tiếp cận tail call cho phép người viết mã C có nhiều quyền kiểm soát hơn
Tham khảo: điều kiện threaded code của MSVC, vấn đề liên quan đến forceinline
Trước đây các tối ưu như tail duplication thay đổi tùy theo quyết định của compiler, còn giờ trình thông dịch có thể trực tiếp biểu đạt dạng mã máy mà nó muốn
Liên kết thảo luận trước đó
Họ chọn Python vì hệ sinh thái VS quá nặng nề so với C#/MAUI
Tkinter thì bất tiện, còn Qt lại có độ khó học khá cao, nên họ dùng kết hợp wxGlade + wxPython
Chỉ cần một dependency duy nhất có thể cài bằng pip, và họ thích cảm giác sử dụng đậm chất Pythonic
Vì vậy các cải thiện runtime trên Windows là tin vui
Làm UI nhanh bằng QtCreator rồi gắn logic bằng Python giúp tốc độ phát triển rất nhanh
Không giống retained mode như Tkinter hay Qt, nó dùng kiểu immediate mode, nên đặc biệt hữu ích cho công cụ nội bộ
Dự án imgui_bundle
Họ nói rằng đã tưởng nó phải được viết bằng assembly cho từng ISA chính rồi
[[msvc::musttail]]là thuộc tính rất mới, chỉ được thêm vào MSVC 14.50 (ra mắt tháng trước), vậy mà nhóm CPython đã tận dụng nó trong vài tuần để đạt cải thiện hiệu năngTài liệu MSVC musttail
Guido ưu tiên tính đơn giản của mã nguồn, nên việc đưa JIT vào diễn ra chậm, rồi sau đó mới có các nỗ lực như PEP 744 (JIT Compilation)
Tối ưu hóa bằng assembly là ác mộng bảo trì, và nút thắt thực sự của Python là hệ thống đóng gói
PyPy nhanh nhờ JIT nhưng lại không tương thích với extension C
Mô hình luồng của Python cũng khiến việc tối ưu khó hơn
Trong khi đó JS là single-thread nên đơn giản hơn
Python còn có thể lách qua bằng extension C, nên áp lực tối ưu chính CPython từ trước tới nay thấp hơn
Ngoài ra CPython không thể phá vỡ tính tương thích vì có một hệ sinh thái extension C khổng lồ
Còn V8 thì có thể tự do thay đổi cấu trúc bên trong
Ngoài ra nó còn phải duy trì ABI C ổn định, nên JIT khó có thể tự do phân tích mã
Có nhắc đến việc PyPy đã vất vả ra sao khi phải đáp ứng các ràng buộc này
Ngoài ra JS chỉ cần hỗ trợ JS thuần, còn Python phải duy trì hệ sinh thái extension bên ngoài nên bị hạn chế nhiều hơn trong tối ưu hóa
Họ cũng chia sẻ rằng mình từng dùng
mitatađể đo hiệu năng thư viện JSPR tối ưu hóa Immer JS
Giải thích trên Wikipedia, ví dụ Matplotlib
Nó trực quan hóa phân phối theo dạng đối xứng, nhưng làm mượt có thể bóp méo phân phối thực tế, và cũng bị chê là tốn không gian
Trong thảo luận HN còn có ý kiến cho rằng half-violin plot tốt hơn
Hình minh họa
Họ châm biếm các đặc điểm điển hình của bài do AI viết như đoạn văn ngắn, giọng điệu quá tích cực, thiếu chiều sâu, v.v.