2010-04-07 22 views
216

Từ Google Open Source Blog:PyPy - Làm sao nó có thể đánh bại CPython?

PyPy là một reimplementation của Python bằng Python, sử dụng kỹ thuật tiên tiến để cố gắng đạt được hiệu suất tốt hơn hơn CPython. Nhiều năm làm việc chăm chỉ cuối cùng đã được đền đáp. Tốc độ của chúng tôi kết quả thường đánh bại CPython, từ từ chậm hơn một chút, đến tăng tốc lên tới 2x trên mã ứng dụng thực, để tăng tốc lên tới 10x trên các điểm chuẩn nhỏ.

Làm cách nào có thể? Việc triển khai Python nào được sử dụng để triển khai PyPy? CPython? Và cơ hội của một PyPyPy hoặc PyPyPyPy đánh bại điểm số của họ là gì?

(Trên một lưu ý liên quan ... tại sao mọi người sẽ cố gắng một cái gì đó như thế này?)

+32

Nitpick: PyPy * là * PyPyPy. Hãy nghĩ về tiền tố Py- * làm toán tử chiếu. – u0b34a0f6ae

+0

Ok. vì vậy PyPy nên được ưa thích hơn để CPython? nó có bất kỳ hạn chế nào không? – balki

+8

PyPy là tuyệt vời khi tối ưu hóa thời gian chạy, nhưng các phần tử khác nhau của nó làm cho nó [không tương thích] (https://bitbucket.org/pypy/compatibility/wiki/Home) với một số phần mở rộng C phổ biến. –

Trả lời

133

Q1. Sao có thể như thế được?

Quản lý bộ nhớ thủ công (đó là những gì CPython thực hiện với việc đếm) có thể chậm hơn quản lý tự động trong một số trường hợp.

Hạn chế trong việc triển khai trình thông dịch CPython loại trừ một số tối ưu nhất định mà PyPy có thể thực hiện (ví dụ: khóa hạt mịn).

Như Marcelo đã đề cập, JIT. Có khả năng để bay xác nhận loại của một đối tượng có thể giúp bạn tiết kiệm được nhu cầu làm nhiều dereferences con trỏ để cuối cùng đến phương pháp bạn muốn gọi.

Q2. Việc triển khai Python nào được sử dụng để triển khai PyPy?

Trình thông dịch PyPy được triển khai trong RPython, là một tập con được gõ tĩnh của Python (ngôn ngữ chứ không phải trình thông dịch CPython). - Tham khảo https://pypy.readthedocs.org/en/latest/architecture.html để biết chi tiết.

Q3. Và cơ hội của một PyPyPy hoặc PyPyPyPy đánh bại điểm số của họ là gì?

Điều đó phụ thuộc vào việc triển khai các trình thông dịch giả thuyết này. Ví dụ, nếu một trong số đó lấy nguồn, thực hiện một số phân tích về nó và chuyển đổi nó trực tiếp thành mã assembly cụ thể mục tiêu sau khi chạy trong một thời gian, tôi tưởng tượng nó sẽ khá nhanh hơn CPython.

Cập nhật: Gần đây, trên carefully crafted example, PyPy đã vượt trội so với chương trình C tương tự được biên dịch với gcc -O3. Đó là một trường hợp contrived nhưng hiện một số ý tưởng.

Q4. Tại sao mọi người lại thử một thứ như thế này?

Từ trang web chính thức. https://pypy.readthedocs.org/en/latest/architecture.html#mission-statement

Chúng tôi mong muốn cung cấp:

  • một bản dịch chung và khuôn khổ hỗ trợ cho sản xuất
    triển khai của các ngôn ngữ động, nhấn mạnh một sạch tách
    giữa đặc tả ngôn ngữ và thực hiện
    khía cạnh. Chúng tôi gọi đây là RPython toolchain _.

  • một thực hiện phù hợp, linh hoạt và nhanh chóng của Python_ Ngôn ngữ trong đó sử dụng các toolchain trên để kích hoạt các tính năng cấp cao tiên tiến mới mà không cần phải mã hóa chi tiết ở mức độ thấp.

Bằng cách tách riêng vấn đề theo cách này, thực hiện của chúng ta về Python - và ngôn ngữ động khác - có thể tự động tạo ra một Just-in-Time biên dịch cho bất kỳ ngôn ngữ năng động. Nó cũng cho phép cách tiếp cận kết hợp và kết hợp với các quyết định triển khai, bao gồm nhiều trước đây nằm ngoài tầm kiểm soát của người dùng, chẳng hạn như mô hình nền tảng, bộ nhớ và luồng luồng, thu thập rác thải chiến lược và áp dụng tối ưu hóa hoặc không đến số có JIT ngay từ đầu.

Trình biên dịch Gcc được thực hiện trong C, Trình biên dịch Gaskell GHC được viết bằng Haskell. Bạn có lý do nào để trình biên dịch/biên dịch Python không được viết bằng Python không?

+69

Câu trả lời này là hoàn toàn thiếu lời giải thích chính cho cách PyPy là nhanh; trong khi nó đề cập rằng PyPy không thực sự được triển khai bằng Python, nhưng trong RPython, nó không chỉ ra rằng mã RPython được * biên dịch và tối ưu hóa tĩnh * để tạo ra trình thông dịch PyPy (nó cũng xảy ra cũng là mã Python hợp lệ có thể chạy trên đầu trang của CPython chậm hơn nhiều). Những gì họ đã thực hiện trong "Python bình thường" là RPython "trình biên dịch" (khung dịch thuật được đề cập trong báo giá khối). – Ben

+11

Điều này đang chôn vùi cây đèn. Phần lớn hiệu suất xuất phát từ bản dịch sang C (làm cho trình thông dịch không chậm hơn nhiều so với CPython) và JIT, làm cho đường dẫn nóng nhanh hơn nhiều. – Tobu

+3

* "Cập nhật: Gần đây, trên một ví dụ được chế tạo cẩn thận, PyPy đã vượt trội so với chương trình C tương tự được biên dịch bằng gcc -O3." * Và nếu bạn đọc nhận xét đầu tiên trong bài đăng đó, bạn sẽ thấy rằng người viết bài đăng đó không biết tối ưu hóa thời gian liên kết. Khi bật tối ưu hóa thời gian liên kết, mã C chạy nhanh hơn. – Ali

22

PyPy được thực hiện trong Python, nhưng nó thực hiện một trình biên dịch JIT để tạo ra mã nguồn gốc một cách nhanh chóng.

Lý do để triển khai PyPy trên đầu Python có thể là ngôn ngữ rất hiệu quả, đặc biệt là khi trình biên dịch JIT làm cho hiệu suất của ngôn ngữ máy chủ không liên quan.

+0

Liệu JIT có tạo ra mã Python đang chạy ở cùng cấp với PyPy, hay nó tạo ra mã nguồn gốc thực sự đang chạy ở cấp độ nào mà PyPy thực thi Python đang chạy? – Edmund

+3

Mã nguồn gốc thực (xem [tại đây] (http://pypy.org/download.html#with-a-jit-compiler)); Mã x86 32 bit chính xác. –

11

PyPy được viết bằng Python bị hạn chế. Nó không chạy trên trình thông dịch CPython, theo như tôi biết. Python bị giới hạn là một tập con của ngôn ngữ Python. AFAIK, trình thông dịch PyPy được biên dịch thành mã máy, vì vậy khi cài đặt nó không sử dụng trình thông dịch python khi chạy.

Câu hỏi của bạn dường như mong đợi trình thông dịch PyPy đang chạy trên CPython trong khi thực thi mã. Chỉnh sửa: Có, để sử dụng PyPy, trước tiên bạn dịch mã python PyPy, hoặc thành C và xây dựng với gcc, thành mã byte jvm hoặc mã .Net CLI. Xem Getting Started

+7

PyPy sẽ chạy trên đầu trang của CPython nhưng trong chế độ này, nó không cung cấp tốc độ mà người ta có thể mong muốn. :-) http://codespeak.net/pypy/dist/pypy/doc/getting-started-python.html#id9 –

253

"PyPy là một reimplementation của Python trong Python" là một cách khá gây hiểu lầm để mô tả PyPy, IMHO, mặc dù đó là sự thật về mặt kỹ thuật.

Có hai phần chính của PyPy.

  1. Khung dịch
  2. Các thông dịch viên

Khung dịch là một trình biên dịch. Nó biên dịch RPython mã xuống C (hoặc các mục tiêu khác), tự động thêm vào các khía cạnh như thu thập rác và trình biên dịch JIT. Nó không thể xử lý mã Python tùy ý, chỉ RPython.

RPython là tập con của Python bình thường; tất cả các mã RPython là mã Python, nhưng không phải là cách khác xung quanh. Không có định nghĩa chính thức về RPython, bởi vì RPython về cơ bản chỉ là "tập hợp con của Python có thể được dịch bởi khuôn khổ dịch thuật của PyPy". Nhưng để được dịch, mã RPython phải là được nhập tĩnh (các loại được phỏng đoán, bạn không khai báo chúng, nhưng nó vẫn đúng một loại cho mỗi biến), và bạn không thể làm những việc như khai báo/sửa đổi các hàm/lớp trong thời gian chạy.

Thông dịch viên sau đó là trình thông dịch Python bình thường được viết bằng RPython.

Vì mã RPython là mã Python bình thường, bạn có thể chạy nó trên bất kỳ trình thông dịch Python nào. Nhưng không có tuyên bố tốc độ của PyPy đến từ chạy nó theo cách đó; đây chỉ là một chu kỳ kiểm tra nhanh, bởi vì dịch thông dịch viên mất thời gian dài.

Với điều đó được hiểu, cần rõ ràng rằng các suy đoán về PyPyPy hoặc PyPyPyPy không thực sự có ý nghĩa gì. Bạn có một thông dịch viên được viết bằng RPython. Bạn dịch nó sang mã C thực hiện nhanh Python. Có quá trình dừng lại; không có thêm RPython để tăng tốc bằng cách xử lý nó một lần nữa.

Vì vậy, "Làm thế nào để PyPy có thể nhanh hơn CPython" cũng trở nên khá rõ ràng. PyPy có một triển khai tốt hơn, bao gồm một trình biên dịch JIT (nó thường không hoàn toàn nhanh nếu không có trình biên dịch JIT, tôi tin rằng, điều này có nghĩa là PyPy chỉ nhanh hơn cho các chương trình dễ bị biên dịch JIT). CPython không bao giờ được thiết kế để thực hiện tối ưu hóa cao của ngôn ngữ Python (mặc dù chúng cố gắng làm cho nó được thực hiện tối ưu được tối ưu hóa, nếu bạn làm theo sự khác biệt).


Bit thực sự sáng tạo của dự án PyPy là chúng không viết lược đồ GC tinh vi hoặc trình biên dịch JIT bằng tay. Họ viết trình thông dịch tương đối đơn giản trong RPython, và đối với tất cả RPython là cấp thấp hơn Python, nó vẫn là ngôn ngữ thu gom hướng đối tượng, cao hơn nhiều so với C. Sau đó khung dịch tự động thêm những thứ như GC và JIT. Vì vậy, khung dịch là nỗ lực lớn, nhưng nó áp dụng tốt cho trình thông dịch python Python nhưng họ thay đổi việc triển khai, cho phép tự do hơn trong thử nghiệm để cải thiện hiệu suất (không lo lắng về việc giới thiệu lỗi GC hoặc cập nhật trình biên dịch JIT) đối phó với những thay đổi). Nó cũng có nghĩa là khi họ có được xung quanh để thực hiện một trình thông dịch Python3, nó sẽ tự động nhận được những lợi ích tương tự. Và bất kỳ người phiên dịch nào khác được viết bằng khuôn khổ PyPy (trong đó có một số ở các giai đoạn đánh bóng khác nhau). Và tất cả các thông dịch viên sử dụng khung công tác PyPy sẽ tự động hỗ trợ tất cả các nền tảng được khung công tác hỗ trợ. Vì vậy, lợi ích thực sự của dự án PyPy là tách biệt (càng nhiều càng tốt) tất cả các phần của việc thực hiện một trình thông dịch độc lập nền tảng hiệu quả cho một ngôn ngữ động. Và sau đó đến với một thực hiện tốt của họ ở một nơi, có thể được tái sử dụng trên nhiều thông dịch viên. Đó không phải là một chiến thắng ngay lập tức như "chương trình Python của tôi chạy nhanh hơn bây giờ", nhưng đó là một viễn cảnh tuyệt vời cho tương lai.

Và nó có thể chạy chương trình Python của bạn nhanh hơn (có thể).

+11

Đây là một trong những giải thích tốt nhất mà tôi đã đọc cho đến nay. Tôi thậm chí còn thấy cuộc nói chuyện của David Beazley về PyPy trong PyCon nhưng nó quá khó để nhai. : P – Chirag

+3

Tôi không thể theo dõi sự khác biệt: ( – polvoazul

+27

@polvoazul Sự khác biệt giữa việc triển khai ngôn ngữ * được tối ưu hóa * và tối ưu hóa * * ?, Khi tôi nói CPython là một triển khai được tối ưu hóa tốt, tôi có nghĩa là các nhà phát triển cố gắng thực hiện Một thuật toán nội bộ của trình thông dịch và các cấu trúc dữ liệu dựng sẵn chạy một cách hiệu quả * An * tối ưu hóa việc triển khai thực hiện, OTOH, sẽ phân tích mã * người dùng cuối * và cố gắng tìm ra cách để biến đổi nó thành thực thi hiệu quả hơn – Ben

Các vấn đề liên quan