Hudson River Trading ( HRT ) đã triển khai thành công một phiên bản Python fork tùy chỉnh trên toàn bộ tổ chức của họ, áp dụng lazy imports để giảm đáng kể thời gian khởi động cho các ứng dụng Python. Đội ngũ kỹ thuật của công ty giao dịch này đã dành hơn hai năm để phát triển và di chuyển sang giải pháp này, giúp hoãn việc tải module cho đến khi thực sự cần thiết trong quá trình chạy.
Vấn đề đã khơi dậy sự đổi mới
Kiến trúc monorepo của HRT, mặc dù cho phép hợp tác giữa các nhóm, đã tạo ra một nút thắt hiệu suất đáng kể. Các script Python của họ đang import một số lượng lớn module khi khởi động, với nhiều import thực tế không bao giờ được sử dụng trong quá trình thực thi. Điều này dẫn đến việc các công cụ dòng lệnh mất hàng chục giây để khởi động, Jupyter notebook cần vài phút để tải, và các công việc tính toán phân tán dành nhiều thời gian cho việc import hơn là tính toán thực tế. Vấn đề đặc biệt nghiêm trọng vì các module của họ thường nằm trên hệ thống tập tin phân tán và chứa mã khởi tạo nặng.
Cuộc thảo luận cộng đồng cho thấy điều này không chỉ riêng gì HRT. Nhiều nhà phát triển gặp khó khăn với chi phí import của Python, đặc biệt trong các codebase lớn. Một số phải dùng các giải pháp thủ công như đặt import bên trong hàm hoặc sử dụng các thư viện lazy import hiện có, nhưng những cách tiếp cận này tạo ra thách thức bảo trì và làm giảm khả năng đọc code.
Cải thiện hiệu suất
- Công cụ dòng lệnh: Giảm thời gian khởi động từ hàng chục giây xuống gần như tức thì
- Jupyter notebooks: Loại bỏ độ trễ import 10-15 phút
- Các công việc phân tán: Giảm đáng kể thời gian tải các dependency không sử dụng
- Tổng thể: Cải thiện thời gian khởi động gấp 3 lần (dựa trên các triển khai tương tự)
![]() |
---|
Biểu đồ nến minh họa các chuyển động giá, phản ánh bối cảnh tài chính mà HRT hoạt động và tầm quan trọng của việc import hiệu quả cho các hoạt động giao dịch |
Triển khai kỹ thuật và thách thức
HRT đã mượn khái niệm lazy import từ Python fork Cinder của Meta, triển khai hai sửa đổi cốt lõi cho CPython. Thay vì thực thi import ngay lập tức, trình thông dịch tạo ra các đối tượng placeholder hoãn việc tải module thực tế cho đến khi các tên được import được tham chiếu. Cách tiếp cận này hoạt động minh bạch cho hầu hết các trường hợp sử dụng nhưng có những hạn chế đáng chú ý.
Việc triển khai không thể xử lý import trong hàm do tối ưu hóa biến cục bộ của Python, và wildcard import vẫn không thể làm lazy vì không thể xác định các tên được xuất mà không cần đánh giá. Quan trọng hơn, các module có side effect - những module sửa đổi trạng thái toàn cục trong quá trình import - có thể gây ra lỗi tinh vi khi việc thực thi của chúng bị hoãn lại.
Runtime imports là một cơn ác mộng bảo trì và có thể nhanh chóng phân mảnh codebase. Phân tích tĩnh của import rất đáng mong muốn đến mức hầu như luôn đáng chấp nhận cái giá về hiệu suất khởi tạo.
Bình luận này làm nổi bật một căng thẳng chính trong cách tiếp cận. Trong khi lazy import giải quyết vấn đề hiệu suất, chúng có thể làm cho hành vi code ít dự đoán được hơn.
Hạn chế Kỹ thuật
- Không thể thực hiện import lazy trong phạm vi function
- Không hỗ trợ wildcard imports (
from module import *
) - Các module có side effects cần xử lý đặc biệt
- Thứ tự phụ thuộc import có thể bị phá vỡ
- Các transitive imports ngầm định cần khai báo rõ ràng
Trải nghiệm di chuyển và bài học kinh nghiệm
Quá trình di chuyển đã tiết lộ ba danh mục chính của các vấn đề tương thích. Import side effect gây ra những thách thức debug khó khăn nhất, vì việc đăng ký decorator và cấu hình toàn cục sẽ thực thi vào những thời điểm bất ngờ hoặc không thực thi chút nào. Các phụ thuộc thứ tự import trở nên có vấn đề khi các module có side effect xung đột không còn tải theo trình tự dự đoán được. Ngoài ra, implicit transitive import - nơi code dựa vào các submodule được import bởi các module khác - bị hỏng khi những phụ thuộc đó không thực sự được tải.
HRT đã giải quyết những vấn đề này thông qua sự kết hợp của các khối eager import, danh sách loại trừ cho các gói third-party, và quản lý phụ thuộc rõ ràng. Công ty đã hoàn thành việc di chuyển cùng với nâng cấp Python 3.12, làm cho lazy import trở thành mặc định cho tất cả code Python vào Q2 2025.
Lộ trình di chuyển
- Q1 2023: Phiên bản prototype ban đầu được phát triển trong hackathon nội bộ
- Q2-Q4 2023: Cải tiến triển khai và di chuyển các nhóm đầu tiên
- Q2 2024: Đạt được 50% khả năng tương thích lazy trên toàn bộ monorepo
- Q3 2024: Hoàn thành việc chuyển đổi sang Python 3.12
- Q2 2025: Lazy imports được triển khai làm mặc định trên toàn công ty
Tác động hiệu suất và triển vọng tương lai
Kết quả đã rất đáng kể trên toàn hệ sinh thái Python của HRT. Các công cụ dòng lệnh giờ đây cung cấp phản hồi ngay lập tức thay vì độ trễ khởi động nhiều phút. Quy trình làm việc Jupyter notebook trước đây cần 10-15 phút thời gian import giờ khởi động gần như ngay lập tức. Các công việc tính toán phân tán từng dành nhiều thời gian tải phụ thuộc hơn là thực thi công việc đã thấy cải thiện hiệu quả đáng kể.
Bất chấp thành công, HRT thừa nhận gánh nặng bảo trì của việc duy trì một Python fork. Họ đang khám phá việc đề xuất cú pháp lazy import rõ ràng cho upstream Python, sử dụng từ khóa như lazy import foo thay vì làm cho laziness ngầm định. Cách tiếp cận này sẽ giải quyết mối quan ngại của Python Steering Council về lỗi tinh vi trong khi làm cho lợi ích hiệu suất có sẵn cho cộng đồng Python rộng lớn hơn.
Cuộc thảo luận xung quanh việc triển khai của HRT phản ánh những câu hỏi rộng lớn hơn về đặc điểm hiệu suất của Python và sự đánh đổi giữa tiện lợi và tốc độ trong phát triển phần mềm quy mô lớn.
Tham khảo: Inside HRT's Python Fork: Leveraging PEP 690 for Faster Imports