Những công cụ hoặc cách tiếp cận nào có sẵn để tăng tốc mã được viết bằng Python?


29

Bối cảnh: Tôi nghĩ rằng tôi có thể muốn chuyển một số mã tính toán các sản phẩm vectơ hàm mũ ma trận bằng phương pháp không gian con Krylov từ MATLAB sang Python. (Cụ thể, hàm expmvp của Jitse Niesen , sử dụng thuật toán được mô tả trong bài viết này .) Tuy nhiên, tôi biết rằng trừ khi tôi sử dụng nhiều chức năng từ các mô-đun có nguồn gốc từ các thư viện được biên dịch (nghĩa là tôi chỉ sử dụng Python thô và không có nhiều phần mềm dựng sẵn trong các chức năng), sau đó nó có thể khá chậm.

Câu hỏi: Những công cụ hoặc cách tiếp cận nào có sẵn để giúp tôi tăng tốc mã tôi viết bằng Python để thực hiện? Cụ thể, tôi quan tâm đến các công cụ tự động hóa quy trình càng nhiều càng tốt, mặc dù các cách tiếp cận chung cũng được hoan nghênh.

Lưu ý: Tôi có một phiên bản cũ hơn của thuật toán Jitse và đã không sử dụng nó trong một thời gian. Có thể rất dễ dàng để tạo mã này nhanh, nhưng tôi cảm thấy như nó sẽ là một ví dụ cụ thể tốt, và nó có liên quan đến nghiên cứu của riêng tôi. Tranh luận về cách tiếp cận của tôi để thực hiện thuật toán đặc biệt này trong Python là một câu hỏi hoàn toàn khác.


Tôi đã đưa ra một câu trả lời riêng biệt cho câu hỏi này: scicomp.stackexchange.com/questions/2429/ nam Tôi nghĩ rằng các gợi ý và liên kết ở đó sẽ hữu ích cho bạn.
AlexE

(h / t gửi @AlexE vì đã cho tôi biết điều này) Chắc chắn có sự trùng lặp giữa câu hỏi này, (làm thế nào) viết mô phỏng chạy nhanh hơn? một số chiến lược tốt để cải thiện hiệu suất nối tiếp của mã của tôi là gì? . Một số loại hợp nhất có thể theo thứ tự. Tôi đã đăng về nó trên Meta.
Geoff Oxberry

1
Ngoài các câu trả lời tốt ở đây, hãy xem liên kết này .
Mike Dunlavey

Câu trả lời:


40

Tôi sẽ chia câu trả lời của tôi thành ba phần. Cấu hình, tăng tốc mã python qua c và tăng tốc python qua python. Theo quan điểm của tôi, Python có một số công cụ tốt nhất để xem hiệu suất của mã của bạn sau đó đi sâu vào cổ chai thực tế. Tăng tốc mã mà không cần hồ sơ cũng giống như cố gắng giết một con nai bằng uzi.

Nếu bạn thực sự chỉ quan tâm đến các sản phẩm mat-vec, tôi sẽ khuyên bạn nên dùng scipy.spude .

Các công cụ Python để định hình

mô-đun cấu hình và cProfile : Các mô-đun này sẽ cung cấp cho bạn phân tích thời gian chạy tiêu chuẩn và ngăn xếp cuộc gọi chức năng. Thật tuyệt khi lưu số liệu thống kê của họ và sử dụng mô-đun pstats, bạn có thể xem dữ liệu theo một số cách.

kernprof : công cụ này tập hợp nhiều thói quen để thực hiện những việc như định tuyến theo dòng mã

memory_profiler : công cụ này tạo ra dòng in chân bộ nhớ theo mã của bạn.

Bộ định thời IPython :timeitChức năng này khá hay để thấy sự khác biệt trong các chức năng theo cách tương tác nhanh.

Tăng tốc Python

Cython : cython là cách nhanh nhất để có một vài chức năng trong python và nhận mã nhanh hơn. Bạn có thể trang trí chức năng với biến thể cython của python và nó tạo mã c. Điều này rất dễ duy trì và cũng có thể liên kết với mã viết tay khác trong c / c ++ / fortran khá dễ dàng. Đó là công cụ ưa thích ngày nay.

ctypes : ctypes sẽ cho phép bạn viết các hàm của mình trong c và sau đó gói chúng nhanh chóng với cách trang trí mã đơn giản của nó. Nó xử lý tất cả sự đau đớn của việc truyền từ PyObjects và quản lý gil để gọi hàm c.

Các cách tiếp cận khác tồn tại để viết mã của bạn bằng C nhưng tất cả chúng đều có phần hơn để lấy thư viện C / C ++ và gói nó trong Python.

Phương pháp tiếp cận chỉ dành cho Python

Nếu bạn muốn ở bên trong Python, lời khuyên của tôi là tìm ra dữ liệu nào bạn đang sử dụng và chọn các loại dữ liệu chính xác để thực hiện các thuật toán của bạn. Theo kinh nghiệm của tôi, bạn thường sẽ nhận được nhiều hơn nữa bằng cách tối ưu hóa cấu trúc dữ liệu của bạn sau đó bất kỳ hack c cấp thấp nào. Ví dụ:

numpy : một mảng dự phòng rất nhanh cho các hoạt động được thực hiện của các mảng

numexpr : một trình tối ưu hóa biểu thức mảng numpy. Nó cho phép các biểu thức mảng numpy đa luồng và cũng thoát khỏi vô số lỗi tạm thời do các hạn chế của trình thông dịch Python.

blist : một triển khai b-cây của một danh sách, rất nhanh để chèn, lập chỉ mục và di chuyển các nút bên trong của danh sách

gấu trúc : khung dữ liệu (hoặc bảng) phân tích rất nhanh trên các mảng.

pytables : các bảng phân cấp có cấu trúc nhanh (như hdf5), đặc biệt tốt cho các tính toán và truy vấn cốt lõi đối với dữ liệu lớn.


3
Bạn cũng có thể sử dụng ctypes để gọi các thói quen của Fortran.
Matthew Emmett


Nói về mã gói, còn f2py thì sao?
astrojuanlu

f2py là một công cụ tuyệt vời và được nhiều người trong cộng đồng sử dụng. fwrap là một sự thay thế gần đây hơn vì f2py cho thấy tuổi của nó nhưng nó không thực sự hoàn thiện.
aterrel

Cảm ơn! Đây là những loại tài nguyên tôi đang tìm kiếm. Tôi chỉ nhận thức được một vài trong số chúng, và chỉ khi đi qua (hoặc nhìn vào chúng trên Internet). Aron cứ nhắc đến numexpr. Làm thế nào mà làm việc? Điều đó sẽ áp dụng?
Geoff Oxberry

7

Trước hết, nếu có triển khai C hoặc Fortran (hàm MATLAB MEX?), Tại sao bạn không viết trình bao bọc Python?

Nếu bạn muốn triển khai của riêng bạn không chỉ là một trình bao bọc, tôi thực sự khuyên bạn nên sử dụng mô-đun numpy cho công cụ đại số tuyến tính. Đảm bảo rằng nó được liên kết với một blas được tối ưu hóa (như ATLAS, GOTOblas, uBLAS, Intel MKL, ...). Và sử dụng Cython hoặc dệt. Đọc bài viết Hiệu suất Python này để có một giới thiệu tốt và điểm chuẩn. Các triển khai khác nhau trong bài viết này có sẵn để tải về tại đây nhờ Travis Oliphant (Numpy-guru).

Chúc may mắn.


Bài viết về Hiệu suất Python đó có vẻ hơi cũ, nó không đề cập đến một số công cụ mới hơn có sẵn như numexpr.
Aron Ahmadia

Tôi thực sự bỏ qua numexpr. Sẽ thật tuyệt khi chạy cùng một tiêu chuẩn laplace với numexpr ...
GertVdE

scipy.weavevẫn sử dụng và phát triển? Có vẻ như bài viết Performance Python cho thấy nó có thể được sử dụng nhanh và mang lại sự cải thiện khá tốt về tốc độ nhưng tôi hiếm khi thấy nó được đề cập bên ngoài bài viết đó.
Ken

@Ken: scipy.weave, theo như tôi biết, không còn được phát triển tích cực. Nó được giữ để tương thích ngược nhưng các dự án mới được khuyến khích sử dụng Cython.
GertVdE

Đối với GotoBLAS và NumPy / SciPy, xem der-schnorz.de/2012/06/optimized-linear-acheebra-and-numpyscipy
AlexE

4

Về cơ bản tôi đồng ý với các câu trả lời khác. Các tùy chọn tốt nhất cho pythonmã số nhanh là

  • Sử dụng các thư viện chuyên ngành như numpy
  • bọc mã hiện có của bạn để pythonchương trình của bạn có thể gọi nó trực tiếp

Nhưng nếu bạn muốn lập trình toàn bộ thuật toán từ đầu (tôi trích dẫn: "Tôi chỉ sử dụng Python thô") thì bạn có thể muốn xem xét http://pypy.org/ triển khai JIT (Just In Time) python. Tôi đã không thể sử dụng nó cho dự án của mình (vì điều đó phụ thuộc vào numpyvà các pypychàng trai đang làm việc một cách chính xác để hỗ trợ điều đó) nhưng các điểm chuẩn khá ấn tượng ( http://speed.pypy.org/ )


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.