Nói đơn giản, Cython là siêu ngôn ngữ của Python có thể biên dịch thành C.
Như chúng ta đã biết, Python nổi tiếng là một trong những ngôn ngữ lập trình súc tích, dễ sử dụng.
Nhưng khi nói về TỐC ĐỘ thì gần như không có số có má.
Vì thế người ta tìm ra giải pháp với Cython.
Với Cython, chúng ta có thể có thể tăng hiệu suất có thể từ vài phần trăm đến vài lần tùy thuộc vào loại nhiệm vụ.
Đối với công việc bị ràng buộc bởi các loại native object của Python, sự tăng tốc không nhiều lắm.
Nhưng đối với các hoạt động bằng số hoặc bất kỳ hoạt động nào không liên quan đến nội bộ của Python, thì mức tăng có thể rất lớn.
Theo cách này, những điều mà người ta nói về hiệu suất của Python không còn đúng nữa.
Cython cho phép bạn có thể vượt qua nhiều giới hạn riêng của Python, hoặc vượt qua chúng hoàn toàn.
Cython: Python chạy nhanh như C
Trong bài viết này, chúng ta tìm hiểu cơ bản về Cython và tạo một ứng dụng Python đơn giản sử dụng Cython để tăng tốc độ thực thi của nó xem thế nào nhé.
Biên dịch Python thành C
Mã Python có thể thực hiện cuộc gọi trực tiếp vào các module C.
Các module C đó có thể là thư viện C chung hoặc thư viện được xây dựng riêng để hoạt động với Python.
Cython tạo ra loại module thứ hai: Các thư viện C nói chuyện với các phần tử Python và có thể được bọc cùng với mã Python hiện có.
Theo thiết kế, mã Cython trông rất giống mã Python.
Nếu bạn cung cấp cho trình biên dịch Cython một chương trình Python, nó vẫn chạy, nhưng chưa thể tăng tốc như mong muốn.
Nhưng nếu bạn thay đổi mã Python bằng các kiểu cú pháp đặc biệt của Cython, lúc này chương trình Python của bạn có thể có tốc độ của C.
Lưu ý rằng phương pháp tiếp cận của Cython là GIA TĂNG.
Có nghĩa là bạn có thể bắt đầu viết chương trình Python như thông thường.
Sau đó, bạn quay lại thay đổi, chỉnh sửa tại chỗ cho mã thay vì viết ứng dụng từ đầu theo kiểu Cython.
Cách tiếp cận này phù hợp với bản chất của các vấn đề hiệu suất phần mềm nói chung.
Trong hầu hết các chương trình, phần lớn mã sử dụng nhiều CPU tập trung ở một vài điểm nóng, một phiên bản của nguyên tắc Pareto, còn được gọi là quy tắc 80/20.
Có nghĩa là, 80% hiệu quả tăng tốc đạt được do thay đổi ở 20% mã.
Chính vì thế,
Bạn chỉ cần dịch 20% mã Python đó sang Cython và bạn sẽ đạt được khả năng tăng tốc như mong muốn.
Phần còn lại của chương trình vẫn cứ để nguyên như Python thông thường là được.
Làm thế nào để sử dụng Cython?
Để hiểu cách sử dụng Cython, hãy xem xét các ví dụ bên dưới đây:
* Ví dụ được lấy từ Cython Documentation
def f(x):
return x ** 2 - x
def integrate_f(a, b, N):
s = 0
dx = (b - a)/N
for i in range(N):
s += f(a + i * dx)
return s * dx
Đây là một ví dụ, một triển khai không hiệu quả của một hàm tích phân.
Là mã Python thuần, nó chậm, vì Python phải chuyển đổi qua lại giữa các kiểu số gốc của máy và các loại đối tượng bên trong của chính nó.
Bây giờ hãy thử xem phiên bản Cython của ví dụ trên, với các bổ sung kiểu Cython được dưới:
cdef double f(double x):
return x ** 2 - x
def integrate_f(double a, double b, int N):
cdef int i
cdef double s, x, dx
s = 0
dx = (b - a)/N
for i in range(N):
s += f(a + i * dx)
return s * dx
Nếu chúng ta khai báo rõ ràng các loại biến, cho cả các tham số và các biến được sử dụng trong phần thân của hàm (double
, int
, v.v.), Cython sẽ dịch tất cả chúng sang C.
Chúng ta cũng có thể sử dụng từ khóa cdef
để xác định các hàm được triển khai chủ yếu trong C để tăng thêm tốc độ, mặc dù các hàm đó chỉ có thể được gọi bởi các hàm Cython khác chứ không phải bởi các tập lệnh Python.
Stefan Behnel chỉ ra cách Cython có thể được sử dụng để biên dịch và tăng tốc mã Python, sử dụng các thư viện và cấu trúc dữ liệu gốc nhanh trong hội nghị EuroPython 2019
Ưu điểm của Cython
Ngoài việc có thể tăng tốc mã mà bạn đã viết, Cython còn có một số ưu điểm khác:
Làm việc với thư viện C bên ngoài nhanh hơn
Các Python package như NumPy được viết bằng C nhưng bao bọc bởi Python interfaces để cho mọi người dễ làm việc với chúng.
Tuy nhiên, sử dụng Python interfaces có thể làm mọi thứ chậm lại.
Vì thế,
Với Cython, chúng cho phép bạn nói chuyện trực tiếp với các thư viện bên dưới mà không cần Python. (Thư viện C ++ cũng được hỗ trợ.)
Bạn có thể sử dụng cả quản lý bộ nhớ C và Python
Nếu bạn sử dụng các đối tượng Python, chúng sẽ được quản lý bộ nhớ và thu gom rác giống như trong Python thông thường.
Nhưng bạn cũng hoàn toàn có thể tạo và quản lý các cấu trúc cấp C của riêng mình và sử dụng malloc
/ free.
Bạn có thể chọn An toàn hoặc Tốc độ khi cần thiết.
Cython tự động thực hiện kiểm tra runtime cho các vấn đề phổ biến xuất hiện trong C, chẳng hạn như truy cập ngoài giới hạn trên một mảng, bằng decorator và chỉ thị trình biên dịch (ví dụ: @boundcheck(false)
).
Do đó, mã C được tạo bởi Cython theo mặc định an toàn hơn nhiều so với mã C được viết thủ công.
Nếu bạn tự tin, bạn cũng không cần kiểm tra chúng trong runtime, thay vào đó, vô hiệu hóa chúng để tăng thêm tốc độ, trên toàn bộ module hoặc chỉ trên các chức năng được chọn.
Cython cũng cho phép bạn truy cập một cách tự nhiên các cấu trúc Python sử dụng giao thức bộ đệm của bộ phận dữ liệu để truy cập trực tiếp vào dữ liệu được lưu trữ trong bộ nhớ (không cần sao chép trung gian).
Cython's "memoryviews" cho phép bạn làm việc với các cấu trúc đó ở tốc độ cao và mức độ an toàn phù hợp với nhiệm vụ.
Cython có thể hưởng lợi từ việc phát hành GIL
Khóa phiên dịch toàn cầu Python (GIL), đồng bộ hóa các luồng trong trình thông dịch, bảo vệ quyền truy cập vào các đối tượng Python và quản lý sự tranh chấp tài nguyên.
Nhưng GIL đã bị chỉ trích rộng rãi và gây trở ngại cho hoạt động của Python, đặc biệt là trên các hệ thống đa lõi.
Nếu bạn có một phần mã không tham chiếu đến các đối tượng Python và hoạt động lâu dài, bạn có thể đánh dấu nó bằng lệnh with nogil:
chỉ thị để cho phép nó chạy mà không cần GIL.
Điều này giải phóng trình thông dịch Python để làm những việc khác và cho phép mã Cython sử dụng nhiều lõi.
Python Type Hinting Syntax
Python có type-hinting syntax được sử dụng chủ yếu bởi các trình kiểm tra mã và trình kiểm tra mã, thay vì trình thông dịch CPython.
Cython có cú pháp tùy chỉnh riêng, nhưng với các phiên bản gần đây của Cython, bạn có thể sử dụng type-hinting syntax để đạt được khả năng gợi ý trong mã cho Cython.
Hạn chế của Cython là gì?
Hãy nhớ rằng Cython cũng chỉ là một công cụ.
Nó không tự động biến mọi phiên bản mã Python thành mã C nhanh chóng.
Để tận dụng tối đa Cython, bạn phải biết sử dụng nó một cách khôn ngoan và hiểu những hạn chế của nó:
Tăng tốc nhỏ cho mã Python thông thường.
Khi Cython bắt gặp mã Python không thể dịch hoàn toàn thành C, nó biến đổi mã đó thành một chuỗi các lệnh gọi C tới nội bộ Python.
Nỗ lực này để đưa trình thông dịch Python thoát khỏi vòng lặp thực thi, giúp mã tăng tốc độ khiêm tốn từ 15 - 20% theo mặc định.
Lưu ý rằng đây là trường hợp tốt nhất. Trong một số tình huống, bạn có thể thấy chẳng những không cải thiện hiệu suất mà còn làm giảm hiệu suất.
Tăng tốc nhỏ cho cấu trúc dữ liệu gốc của Python
Python cung cấp một loạt các cấu trúc dữ liệu string, list, tuples, dictionaries, v.v.
Chúng rất thuận tiện cho các lập trình viên và đi kèm với quản lý bộ nhớ tự động riêng. Nhưng chúng lại chậm hơn C.
Cython cho phép bạn tiếp tục sử dụng tất cả các cấu trúc dữ liệu Python, mặc dù không cần tăng tốc nhiều.
Một lần nữa, đây là vì Cython chỉ đơn giản gọi các C APIs trong Python runtime để tạo và thao tác các đối tượng đó.
Do đó, cấu trúc dữ liệu Python hoạt động giống như mã Python được tối ưu hóa của Cython: Đôi khi bạn thấy nó có thể tăng tốc, nhưng chỉ một chút.
Mã Cython chạy nhanh nhất khi là "C thuần túy"
Nếu bạn có một hàm trong C được gắn nhãn với từ khóa cdef
, và tất cả các biến và hàm nội tuyến của nó gọi đến những thứ khác là C thuần túy, nó sẽ chạy nhanh như C.
Nhưng nếu hàm đó tham chiếu bất kỳ mã Python gốc nào, như cấu trúc dữ liệu Python hoặc gọi tới nội bộ Python thì bạn lại gặp nút thắt cổ chai.
Nhưng may cho bạn,
Cython cung cấp một cách để phát hiện các nút thắt cổ chai này.
Một báo cáo được tạo cho một ứng dụng Cython. Vùng màu trắng là C thuầ túy. Các khu vực màu vàng hiển thị tương tác với các phần bên trong Python. Một chương trình Cython được tối ưu hóa tốt sẽ có càng ít màu vàng càng tốt. (Đọc thêm tại đây)
Ứng dụng càng được tối ưu hóa tốt hơn, sẽ càng ít tương tác với Python.
Cython NumPy
Cython cải thiện việc sử dụng các thư viện xử lý số bên thứ ba dựa trên C như NumPy.
Vì mã Cython biên dịch thành C, nó có thể tương tác trực tiếp với các thư viện đó.
Đặc biệt, NumPy hoạt động tốt với Cython.
Cython có hỗ trợ riêng cho các cấu trúc cụ thể trong NumPy và cung cấp quyền truy cập nhanh vào mảng NumPy.
Và cú pháp NumPy quen thuộc mà bạn sử dụng trong tập lệnh Python thông thường có thể được sử dụng trong Cython.
Tuy nhiên, nếu bạn muốn tạo các ràng buộc gần nhất có thể giữa Cython và NumPy, bạn cần chỉnh sửa thêm cho code bằng cú pháp tùy chỉnh Cython.
Ví dụ, câu lệnh cimport
cho phép mã Cython thấy các cấu trúc mức C trong các thư viện tại thời điểm biên dịch cho các ràng buộc nhanh nhất có thể.
Do NumPy được sử dụng rộng rãi, Cython đã hỗ trợ NumPy thoát khỏi vòng lặp hiệu suất.
Nếu bạn đã cài đặt NumPy, bạn có thể chỉ ra cimport numpy
trong mã của mình, sau đó chỉnh sửa thêm để sử dụng các hàm phù hợp.
Cython profiling
Profiling trong Cython được điều khiển bởi một chỉ thị biên dịch. Nó có thể được thiết lập cho toàn bộ tệp hoặc trên từng chức năng thông qua Cython decorator. Tham khảo thêm tại đây.
Nhờ Cython: Python nhanh như C
Với Cython, bạn không cần chuyển đổi sang bất kỳ ngôn ngữ nào khác. Bạn có thể tiếp tục làm việc với ngôn ngữ Python mà bạn yêu thích.
Nhưng cần phải ghi nhớ là Cython không phải là toàn năng.
Và bạn càng ít đưa đón qua lại giữa Python và Cython, ứng dụng của bạn sẽ chạy càng nhanh.
Chẳng hạn, nếu bạn có một tập hợp các đối tượng bạn muốn xử lý trong Cython thì đừng lặp qua nó trong Python và gọi hàm Cython.
Thay vào đó, hãy truyền toàn bộ tập hợp cho Cython module và lặp qua nó ở đó.
Kỹ thuật này được sử dụng thường xuyên trong các thư viện quản lý dữ liệu, do đó, nó là một mô hình tốt để mô phỏng.
Vì thế, đừng lo lắng về tốc độ trong Python. Điều bạn cần quan tâm khi đến với Python là nó có thể giải quyết vấn đề của bạn mà các ngôn ngữ khác không làm được không?
Nếu có, hãy sử dụng Python.
Còn nếu bạn thực sự quan tâm đến hiệu suất?
Chọn Học Java sẽ tốt hơn.
Nguồn: https://www.infoworld.com/article/3250299/what-is-cython-python-at-the-speed-of-c.html
---
HỌC VIỆN ĐÀO TẠO CNTT NIIT - ICT HÀ NỘI
Dạy học Lập trình chất lượng cao (Since 2002). Học làm Lập trình viên. Hành động ngay!
Đc: Tầng 3, 25T2, N05, Nguyễn Thị Thập, Cầu Giấy, Hà Nội
SĐT: 02435574074 - 0914939543 - 0353655150
Email: hello@niithanoi.edu.vn
Fanpage: https://facebook.com/NIIT.ICT/
#niit #niithanoi #niiticthanoi #hoclaptrinh #khoahoclaptrinh #hoclaptrinhjava #hoclaptrinhphp #python #java #php