Tại sao mã Python của tôi quá chậm?

Chọn Python làm ngôn ngữ lập trình chính có nhiều lợi thế rõ ràng, bao gồm hỗ trợ rộng rãi cho lập trình khoa học và thư viện AI

Tuy nhiên, có một số nhược điểm khi sử dụng Python trong môi trường thời gian thực. Bài đăng này là bài thứ hai trong loạt bài về việc chọn ngăn xếp công nghệ phần mềm cho một công ty hình ảnh y tế và sẽ mô tả ngắn gọn vấn đề chính về những hạn chế về hiệu suất, lý do của hiện tượng này và các phương pháp tiềm năng để giải quyết những vấn đề này

GIL cho phép thực hiện chỉ một luồng tại một thời điểm trong quy trình HĐH. Để thực hiện lập trình song song các tác vụ chuyên sâu của CPU, phải sử dụng các tính năng đa xử lý. Tuy nhiên, điều quan trọng cần lưu ý là việc tạo ra các quy trình mới, cũng như quá trình chuyển ngữ cảnh, cần có thời gian.

Không giống như các ngôn ngữ lập trình phổ biến khác bao gồm C# hoặc JAVA, Python là ngôn ngữ được gõ động và thông dịch. Nó chậm chủ yếu do tính chất năng động và tính linh hoạt của nó

Cả C# và Java đều được biên dịch thành “Ngôn ngữ trung gian”, chẳng hạn như IL cho Java và CIL cho C# và sử dụng trình biên dịch JIT [chỉ trong thời gian] cho mã máy. Trình biên dịch JIT có thể thực hiện việc thực thi nhanh hơn bằng cách biết kiến ​​trúc CPU mục tiêu và cho phép thực hiện tối ưu hóa trong thời gian chạy. Trình tối ưu hóa JIT tốt sẽ xem phần nào của ứng dụng đang được thực thi thường xuyên và tối ưu hóa chúng

Ngoài ra, kiểu gõ tĩnh của các ngôn ngữ này cho phép trình biên dịch thực hiện nhiều tối ưu hóa hơn nữa

Tuy nhiên, cách gõ động của Python khiến nó khó tối ưu hóa, vì trình thông dịch có ít thông tin về mã hơn nhiều so với ngôn ngữ gõ tĩnh.

Hành động đầu tiên trong việc giải quyết vấn đề hiệu suất là xác định vị trí nút cổ chai. Trong hầu hết các trường hợp sử dụng, giới hạn tốc độ của Python sẽ không đáng chú ý. Khu vực bị ảnh hưởng nhiều nhất là các tác vụ sử dụng nhiều CPU, chẳng hạn như tính toán số

Dưới đây là một số giải pháp có thể áp dụng để giải quyết vấn đề này

  1. Đa xử lý để bỏ qua giới hạn GIL
  2. Các thư viện bên ngoài nhanh hơn và giải phóng GIL, cho phép xử lý đa luồng
  3. Viết thư viện C++ của riêng bạn
  4. Numba, giúp tăng tốc Python bằng cách biên dịch JIT thành mã gốc

Một số thư viện bên ngoài như Numpy và Scipy sử dụng các triển khai C++ hiệu quả có thể tăng tốc các tác vụ tiêu chuẩn. Một vấn đề phát sinh khi các thư viện đó không thể cung cấp các giải pháp được triển khai trước cho các tính toán cụ thể

Một tùy chọn khác là viết thư viện C++ của riêng bạn và sau đó bọc nó bằng các công cụ, chẳng hạn như Boost. Python, để tạo API thân thiện với Python

Numba là trình biên dịch JIT dành cho Python giúp tăng tốc các hàm Python nặng tính toán và tập trung vào tính toán [e. g. vòng lặp]. Nó cũng hỗ trợ các thư viện tiêu chuẩn như Numpy, không giống như các trình biên dịch Python khác, cho phép mã được viết bằng Python mà không cần thay đổi. Sử dụng Numba chỉ yêu cầu thêm các trình trang trí vào các chức năng của bạn trong khi triển khai chúng trong Python thông thường

Trình trang trí Numba chứa khai báo các loại tham số chức năng và một số đối số cho việc thực thi Numba [e. g. lưu trữ kết quả chức năng, sử dụng GIL, v.v. ]

[nguồn]

Numba tạo mã máy được tối ưu hóa từ mã Python thuần túy bằng cơ sở hạ tầng trình biên dịch LLVM. Tốc độ mã khi sử dụng Numba có thể so sánh với mã tương tự trong C, C++ hoặc Fortran

Đầu tiên, hàm Python được lấy, tối ưu hóa và chuyển đổi thành biểu diễn trung gian của Numba. Sau đó, do kết quả của kiểu suy luận, nó được chuyển đổi thành mã có thể hiểu được LLVM. Mã này sau đó được đưa vào trình biên dịch JIT của LLVM để đưa ra mã máy. Quá trình biên dịch JIT cũng có thể được thực hiện ngoại tuyến để cải thiện hiệu suất

Python là ngôn ngữ cấp cao [hơn C hoặc C++], do đó Python tự quản lý các chi tiết của chương trình như cấp phát bộ nhớ, cấp phát bộ nhớ, con trỏ, v.v. Điều này làm cho các lập trình viên viết mã bằng Python dễ dàng hơn. Mã Python đầu tiên được biên dịch thành Mã Byte python. Quá trình chuyển đổi trình thông dịch Byte Code diễn ra nội bộ và hầu hết được ẩn khỏi nhà phát triển. Mã byte là lập trình cấp thấp và độc lập với nền tảng. Biên dịch mã byte là tăng cường thực thi mã nguồn. Mã nguồn được biên dịch thành mã byte sau đó được thực thi từng cái một trong máy ảo của Python để thực hiện các thao tác. Máy ảo là một thành phần bên trong của Python

Mã Python nội bộ được giải thích trong thời gian chạy thay vì được biên dịch thành mã gốc do đó chậm hơn một chút.  

Chạy tập lệnh Python v/s chạy mã C/C++

con trăn. Đầu tiên nó được biên dịch thành Byte Code. Mã Byte này sau đó được giải thích và thực thi bởi PVM [Máy ảo Python]

C/C++. Mã nguồn được biên dịch thành Mã nhị phân có thể được CPU thực thi trực tiếp giúp chúng hoạt động hiệu quả hơn

Chủ Đề