Python và C có thể hoạt động cùng nhau không?
Một siêu bộ Python biên dịch thành C, Cython kết hợp sự dễ dàng của Python với tốc độ của mã gốc. Dưới đây là hướng dẫn nhanh để tận dụng tối đa Cython trong các chương trình Python của bạn Show
Nhà văn cao cấp, InfoWorld. Mục lục Cho xem nhiều hơn Python nổi tiếng là một trong những ngôn ngữ lập trình tiện lợi nhất, được trang bị phong phú và hết sức hữu ích. Tốc độ thực hiện? Nhập Cython. Ngôn ngữ Cython là một siêu ngôn ngữ của Python biên dịch thành C. Điều này giúp tăng hiệu suất có thể từ vài phần trăm đến vài bậc độ lớn, tùy thuộc vào nhiệm vụ hiện tại. Đối với công việc bị ràng buộc bởi các loại đối tượng gốc của Python, tốc độ tăng tốc sẽ không lớn. Nhưng đối với các hoạt động số hoặc bất kỳ hoạt động nào không liên quan đến nội bộ của Python, lợi nhuận có thể rất lớn Với Cython, bạn có thể bỏ qua nhiều giới hạn bản địa của Python hoặc vượt qua chúng hoàn toàn—mà không phải từ bỏ sự dễ dàng và tiện lợi của Python. Trong bài viết này, chúng ta sẽ tìm hiểu các khái niệm cơ bản đằng sau Cython và tạo một ứng dụng Python đơn giản sử dụng Cython để tăng tốc một trong các chức năng của nó Biên dịch Python sang CMã Python có thể thực hiện cuộc gọi trực tiếp vào các mô-đun C. Các mô-đun 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 mô-đun thứ hai. Thư viện C nói chuyện với nội bộ của Python và có thể đi kèm với mã Python hiện có Mã Cython trông rất giống mã Python, theo thiết kế. Nếu bạn cung cấp cho trình biên dịch Cython một chương trình Python (Python 2. x và Python3. x đều được hỗ trợ), Cython sẽ chấp nhận nó như hiện tại, nhưng không có khả năng tăng tốc riêng nào của Cython sẽ phát huy tác dụng. Nhưng nếu bạn trang trí mã Python bằng các chú thích loại theo cú pháp đặc biệt của Cython, thì Cython sẽ có thể thay thế các đối tượng Python chậm tương đương với C nhanh Lưu ý rằng cách tiếp cận của Cython là gia tăng. Điều đó có nghĩa là nhà phát triển có thể bắt đầu với ứng dụng Python hiện có và tăng tốc ứng dụng đó bằng cách thực hiện các thay đổi tại chỗ đối với mã, thay vì viết lại toàn bộ ứng dụng Cách tiếp cận này phù hợp với bản chất của các vấn đề về 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 số đ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”. Do đó, hầu hết mã trong ứng dụng Python không cần phải được tối ưu hóa hiệu suất, chỉ cần một số phần quan trọng. Bạn có thể dịch từng bước các điểm nóng đó sang Cython để đạt được mức tăng hiệu suất mà bạn cần ở nơi quan trọng nhất. Phần còn lại của chương trình có thể vẫn ở dạng Python mà không cần làm thêm Cách sử dụng CytonHãy xem xét đoạn mã sau, được lấy từ tài liệu của Cython
Đây là một ví dụ về đồ chơi, một cách triển khai hàm tích phân không hiệu quả lắm. Là mã Python thuần túy, nó chậm, vì Python phải chuyển đổi qua lại giữa các loại 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 xem xét phiên bản Cython của cùng một mã, với phần bổ sung Cython được gạch dưới
Nếu chúng ta khai báo rõ ràng các loại biến, cho cả tham số của hàm và các biến được sử dụng trong phần thân của hàm ( Lưu ý rằng mã thực tế của chúng tôi đã thay đổi rất ít. Tất cả những gì chúng tôi đã làm là thêm khai báo kiểu vào mã hiện có để tăng hiệu suất đáng kể Giới thiệu về cú pháp 'Python thuần túy' của CythonCython cung cấp hai cách để viết mã của nó. Ví dụ trên sử dụng cú pháp ban đầu của Cython, được phát triển trước khi cú pháp gợi ý kiểu Python hiện đại ra đời. Nhưng một cú pháp Cython mới hơn được gọi là chế độ Python thuần túy cho phép bạn viết mã gần với cú pháp của Python hơn, bao gồm cả các khai báo kiểu Đoạn mã trên, sử dụng chế độ Python thuần túy, sẽ giống như thế này
Chế độ Python thuần túy Cython dễ hiểu hơn một chút và cũng có thể được xử lý bằng các công cụ linting Python gốc. Nó cũng cho phép bạn chạy mã nguyên trạng mà không cần biên dịch (mặc dù không có lợi ích về tốc độ). Thậm chí có thể chạy mã có điều kiện tùy thuộc vào việc nó có được biên dịch hay không. Thật không may, một số tính năng của Cython, chẳng hạn như làm việc với các thư viện C bên ngoài, không khả dụng ở chế độ Python thuần túy Tìm hiểu thêm về chế độ Python thuần túy của CythonBạn muốn tiến xa hơn với Cython? Ưu điểm của CytonNgoài khả năng tăng tốc mã bạn đã viết, Cython còn mang lại một số lợi thế khác Hiệu suất nhanh hơn khi làm việc với các thư viện C bên ngoàiCác gói Python như NumPy bọc các thư viện C trong giao diện Python để giúp chúng dễ dàng làm việc với. Tuy nhiên, qua lại giữa Python và C thông qua các trình bao bọc đó có thể làm mọi thứ chậm lại. Cython 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 cản trở. (Các thư viện C++ cũng được hỗ trợ. ) Bạn có thể sử dụng cả quản lý bộ nhớ C và PythonNế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. Nếu muốn, bạn cũng 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 0 để làm việc với chúng. Chỉ cần nhớ để làm sạch sau khi chính mìnhBạn có thể lựa chọn an toàn hoặc tốc độ khi cần thiếtCython tự động thực hiện kiểm tra thời gian chạy đối với các sự cố phổ biến xuất hiện trong C, chẳng hạn như truy cập vượt quá giới hạn trên một mảng, bằng cách trang trí và chỉ thị trình biên dịch (e. g. , 1). Do đó, mã C do Cython tạo theo mặc định an toàn hơn nhiều so với mã C cuộn thủ công, mặc dù có khả năng phải trả giá bằng hiệu năng thô.Nếu bạn tự tin rằng mình sẽ không cần những kiểm tra đó trong thời gian chạy, bạn có thể tắt chúng để tăng thêm tốc độ, trên toàn bộ mô-đun 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 nguyên bản các cấu trúc Python sử dụng giao thức bộ đệm để 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). Chế độ xem bộ nhớ của Cython cho phép bạn làm việc với các cấu trúc đó ở tốc độ cao và với mức độ an toàn phù hợp với nhiệm vụ. Chẳng hạn, dữ liệu thô bên dưới chuỗi Python có thể được đọc theo cách này (nhanh) mà không cần phải trải qua thời gian chạy Python (chậm) Mã Cython C có thể hưởng lợi từ việc phát hành GILKhóa phiên dịch toàn cầu của Python, hoặc 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ý tranh chấp tài nguyên. Nhưng GIL đã bị chỉ trích rộng rãi như một trở ngại đối với Python hoạt động tốt hơn, đặc biệt là trên các hệ thống đa lõi Nếu bạn có một đoạn mã không tham chiếu đến các đối tượng Python và thực hiện một thao tác chạy dài, bạn có thể đánh dấu đoạn mã đó bằng lệnh 2 để cho phép đoạn mã đó chạy mà không cần GIL. Điều này giải phóng trình thông dịch Python để tạm thời làm những việc khác và cho phép mã Cython sử dụng nhiều lõi (với công việc bổ sung)Cython có thể được sử dụng để che khuất mã Python nhạy cảmCác mô-đun Python rất dễ dịch ngược và kiểm tra, nhưng các tệp nhị phân đã biên dịch thì không. Khi phân phối ứng dụng Python cho người dùng cuối, nếu bạn muốn bảo vệ một số mô-đun của nó khỏi bị rình mò thông thường, bạn có thể làm như vậy bằng cách biên dịch chúng bằng Cython Tuy nhiên, xin lưu ý rằng việc che giấu như vậy là tác dụng phụ của các khả năng của Cython, không phải là một trong các chức năng dự định của nó. Ngoài ra, không thể dịch ngược hoặc thiết kế ngược một tệp nhị phân nếu một tệp được dành riêng hoặc đủ quyết tâm. Và, như một quy tắc chung, các bí mật, chẳng hạn như mã thông báo hoặc thông tin nhạy cảm khác, không bao giờ được ẩn trong các tệp nhị phân—chúng thường rất dễ bị lộ bằng một kết xuất hex đơn giản Bạn có thể phân phối lại các mô-đun do Cython biên dịchNếu bạn đang xây dựng một gói Python để phân phối lại cho những người khác, nội bộ hoặc thông qua PyPI, thì các thành phần do Cython biên dịch có thể được đưa vào gói đó. Các thành phần đó có thể được biên dịch trước cho các kiến trúc máy cụ thể, mặc dù bạn sẽ cần xây dựng các bánh xe Python riêng cho từng kiến trúc. Nếu không, người dùng có thể biên dịch mã Cython như một phần của quy trình thiết lập, miễn là có trình biên dịch C trên máy đích Hạn chế của CythonHãy nhớ rằng Cython không phải là cây đũa thần. Nó không tự động biến mọi phiên bản mã Python tẻ nhạt thành mã C cực nhanh. Để tận dụng tối đa Cython, bạn phải 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 tối thiểu cho mã Python thông thườngKhi Cython gặp mã Python, nó không thể dịch hoàn toàn sang C, nó sẽ biến mã đó thành một loạt lệnh gọi C đến phần bên trong của Python. Điều này tương đương với việc đưa trình thông dịch của Python ra khỏi vòng lặp thực thi, giúp mã tăng tốc khiêm tốn từ 15 đến 20 phần trăm theo mặc định. Lưu ý rằng đây là trường hợp tốt nhất; . Đo lường hiệu suất trước và sau để xác định những gì đã thay đổi Tăng tốc một chút cho cấu trúc dữ liệu Python gốcPython cung cấp một loạt cấu trúc dữ liệu—chuỗi, danh sách, bộ dữ liệu, từ điển, v.v. Chúng cực kỳ tiện lợi cho các nhà phát triển và chúng có tính năng quản lý bộ nhớ tự động của riêng chúng. Nhưng chúng chậm hơn C thuần túy 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 tăng tốc nhiều. Một lần nữa, điều này là do Cython chỉ đơn giản gọi các API C trong thời gian chạy Python để tạo và thao tác các đối tượng đó. Do đó, các cấu trúc dữ liệu Python hoạt động giống như mã Python được tối ưu hóa cho Cython nói chung. Đôi khi bạn nhận được một sự thúc đẩy, nhưng chỉ một chút. Để có kết quả tốt nhất, hãy sử dụng các biến và cấu trúc C. Tin tốt là Cython giúp bạn dễ dàng làm việc với chúng Mã Cython chạy nhanh nhất khi ở 'thuần C'Nếu bạn có một hàm trong C được gắn nhãn với từ khóa May mắn thay, Cython cung cấp một cách để phát hiện những tắc nghẽn này. báo cáo mã nguồn cho biết nhanh phần nào trong ứng dụng Cython của bạn là C thuần túy và phần nào tương tác với Python. Ứng dụng càng được tối ưu hóa tốt thì càng ít tương tác với Python Báo cáo mã nguồn được tạo cho ứng dụng Cython. Các khu vực màu trắng là C tinh khiết; . 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. Dòng cuối cùng được mở rộng hiển thị mã C làm cơ sở cho mã Cython tương ứng của nó. Dòng 8 có màu vàng do mã xử lý lỗi mà Cython xây dựng cho phép chia theo mặc định, mặc dù điều đó có thể bị vô hiệu hóa Cython và NumPyCython cải thiện việc sử dụng các thư viện xử lý số của bên thứ ba dựa trên C như NumPy. Vì mã Cython biên dịch thành C nên nó có thể tương tác trực tiếp với các thư viện đó và loại bỏ các nút cổ chai của Python ra khỏi vòng lặp Nhưng NumPy, đặc biệt, 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 các mảng NumPy. Và cùng một 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 nguyên trạng 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 trang trí thêm mã bằng cú pháp tùy chỉnh của Cython. Chẳng hạn, câu lệnh 4 cho phép mã Cython xem các cấu trúc cấp C trong thư viện tại thời điểm biên dịch để có các ràng buộc nhanh nhất có thểVì NumPy được sử dụng rộng rãi nên Cython hỗ trợ NumPy “ngay lập tức. ” Nếu bạn đã cài đặt NumPy, bạn chỉ cần ghi 5 trong mã của mình, sau đó thêm phần trang trí khác để sử dụng các chức năng được hiển thị. Hồ sơ và hiệu suất của CythonBạn có được hiệu suất tốt nhất từ bất kỳ đoạn mã nào bằng cách lập hồ sơ cho nó và tận mắt nhìn thấy các điểm tắc nghẽn. Cython cung cấp các hook cho mô-đun cProfile của Python, vì vậy bạn có thể sử dụng các công cụ định hình riêng của Python, như cProfile, để xem mã Cython của bạn hoạt động như thế nào. (Chúng tôi cũng đã đề cập đến công cụ nội bộ của Cython để tìm hiểu xem mã của bạn được dịch sang C hiệu quả như thế nào. ) Điều này giúp ghi nhớ trong mọi trường hợp rằng Cython không phải là ma thuật—các phương pháp thực hiện hợp lý trong thế giới thực vẫn được áp dụng. Bạn càng ít chuyển đổi 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 mà bạn muốn xử lý trong Cython, đừng lặp lại nó trong Python và gọi một hàm Cython ở mỗi bước. Chuyển toàn bộ bộ sưu tập tới mô-đun Cython của bạn và lặp lại ở đó. Kỹ thuật này thường được sử dụng trong các thư viện quản lý dữ liệu, vì vậy đây là một mô hình tốt để mô phỏng trong mã của riêng bạn Chúng tôi sử dụng Python vì nó mang lại sự thuận tiện cho lập trình viên và cho phép phát triển nhanh. Đôi khi năng suất của lập trình viên phải trả giá bằng hiệu suất. Với Cython, chỉ cần thêm một chút nỗ lực là bạn có thể đạt được điều tốt nhất của cả hai thế giới Có liên quan
Serdar Yegulalp là một nhà văn cao cấp tại InfoWorld, tập trung vào học máy, container hóa, devops, hệ sinh thái Python và đánh giá định kỳ Python làm việc với C như thế nào?Mã Python có thể gọi trực tiếp vào các mô-đun C . Các mô-đun 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 mô-đun thứ hai. Các thư viện C nói chuyện với nội bộ của Python và có thể được gói cùng với mã Python hiện có.
Học Python và C cùng lúc có tốt không?Tôi không khuyên bạn nên học nhiều ngôn ngữ lập trình cùng một lúc nếu bạn là người mới bắt đầu. Tuy nhiên, nếu bạn định chọn hai ngôn ngữ bất kỳ, học C++ và Python cùng lúc là một sự kết hợp khá tốt. Hai ngôn ngữ chia sẻ một ngôn ngữ tổ tiên chung, C. Cũng như làm theo cùng một mô hình lập trình
Bạn có thể kết hợp C++ và Python không?Cũng có thể nhúng Python vào chương trình C++ ; . Không cần phải tự biên dịch lại Python bằng C++. |