Python được giải thích hay biên dịch?


76

Đây chỉ là một thắc mắc tôi đã có trong khi đọc về các ngôn ngữ được giải thích và biên dịch.

Ruby chắc chắn là một ngôn ngữ được thông dịch vì mã nguồn được xử lý bởi một trình thông dịch tại điểm thực thi.
Ngược lại, C là ngôn ngữ được biên dịch, vì người ta phải biên dịch mã nguồn trước theo máy và sau đó thực thi. Kết quả này được thực hiện nhanh hơn nhiều.

Bây giờ đến với Python :

  • Mã python ( somefile.py ) khi được nhập sẽ tạo một tệp ( somefile.pyc ) trong cùng thư mục. Hãy để chúng tôi nói việc nhập được thực hiện trong một mô-đun python shell hoặc django. Sau khi nhập, tôi thay đổi mã một chút và thực hiện lại các chức năng đã nhập để thấy rằng nó vẫn đang chạy mã cũ. Điều này cho thấy rằng các tệp * .pyc được biên dịch các tệp python tương tự như tệp thực thi được tạo sau khi biên dịch tệp C, mặc dù tôi không thể thực thi trực tiếp tệp * .pyc.
  • Khi tệp python (somefile.py) được thực thi trực tiếp (./somefile.py hoặc python somefile.py) không có tệp .pyc được tạo và mã được thực thi như thể hiện hành vi được diễn giải.

Những điều này cho thấy rằng một mã python được biên dịch mỗi khi nó được nhập vào trong một quy trình mới để tạo .pyc trong khi nó được diễn giải khi được thực thi trực tiếp.

Vì vậy, loại ngôn ngữ nào tôi nên xem nó là? Giải thích hay tổng hợp? Và làm thế nào để hiệu quả của nó so với các ngôn ngữ được giải thích và biên dịch?

Theo trang Ngôn ngữ diễn giải của wiki , nó được liệt kê là ngôn ngữ được biên dịch thành Mã máy ảo, điều đó có nghĩa là gì?


1
Khi nào có nghi ngờ về việc liệu Ruby có phải là một ngôn ngữ được giải thích không? Khi nó được biên dịch. :) macruby.org
mipadi

8
Điều đáng chú ý là không có ngôn ngữ hiện đại nào được diễn giải theo nghĩa chặt chẽ. Hầu như tất cả chúng đều biên dịch thành mã byte.
Winston Ewert

@Winston Ewert: bravo! Applesoft Basic (vào những năm 1980) được biên dịch mã byte. "Hiện đại" trong trường hợp này, có nghĩa là mọi ngôn ngữ được diễn giải trong bộ nhớ sống với ngoại lệ duy nhất có thể là một số triển khai cơ bản của Dartmouth thô sơ.
S.Lott

6
>> Ngược lại, C là một ngôn ngữ được biên dịch << root.cern.ch/drupal/content/cint
igouy

3
@ S.Lott: Việc gọi quy trình mã thông báo mà các phiên dịch viên BASIC của Applesoft và thập niên 80 đã thực hiện "biên dịch mã byte" là nhiều hơn một chút không rõ ràng. Có, mã chương trình được người dùng nhập vào được lưu trữ trong bộ nhớ ở dạng nén, một byte cho mỗi từ dành riêng, nhưng không có gì được thực hiện ngoài điều đó cho đến khi bạn nhập RUN. Như thể bạn có một trình biên dịch đã thực hiện bước lexing và sau đó xuất ra một luồng mã thông báo phải được sửa lại mỗi khi chương trình được chạy. Hoàn toàn không giống như quá trình biên dịch mã byte hiện đại như được thực hiện bởi, giả sử, javacbao gồm lexing, phân tích cú pháp và tối ưu hóa.
dodgethesteamler

Câu trả lời:


80

Điều đáng chú ý là các ngôn ngữ không được giải thích hoặc biên dịch, mà là các triển khai ngôn ngữ hoặc là giải thích hoặc biên dịch mã. Bạn lưu ý rằng Ruby là một "ngôn ngữ được dịch", nhưng bạn có thể biên dịch Ruby à la MacRuby , vì vậy nó không phải lúc nào cũng là ngôn ngữ được dịch.

Khá nhiều mỗi triển khai Python bao gồm một trình thông dịch (chứ không phải là trình biên dịch). Các .pyctệp bạn thấy là mã byte cho máy ảo Python (tương tự như .classcác tệp của Java ). Chúng không giống như mã máy được tạo bởi trình biên dịch C cho kiến ​​trúc máy gốc. Tuy nhiên, một số triển khai Python bao gồm một trình biên dịch đúng lúc sẽ biên dịch mã byte Python thành mã máy gốc.

(Tôi nói "khá nhiều mỗi" vì tôi không biết bất kỳ trình biên dịch máy gốc nào cho Python, nhưng tôi không muốn khẳng định rằng không có nơi nào tồn tại ở bất cứ đâu.)


Tùy thuộc vào định nghĩa của bạn, trình biên dịch máy gốc cho Python tồn tại. Một số chỉ biên dịch một tập hợp con của trăn. Những người khác thực hiện tất cả python nhưng sử dụng API python để thực sự thực hiện các hoạt động mà nó không thể thực hiện trong C.
Winston Ewert

Tôi nghĩ rằng bạn đang thực sự mô tả rằng Python là cái mà tôi sẽ gọi là 'bán tổng hợp' hoặc thực sự có thể được biên dịch đầy đủ. Bằng cách biên dịch bán, tôi có nghĩa là vì nó thường được biên dịch thành tệp .pyc 'ngôn ngữ trung gian' được sử dụng bởi Máy ảo Python, nên nó thường được chạy từ dạng 'bán tổng hợp' này, thường làm cho mã nhanh hơn giải thích thời gian chạy đơn giản của mã giải thích. Thật thú vị, mã được biên dịch đôi khi có thể nhanh hơn mã được biên dịch nguyên gốc (ví dụ: C # thường nhanh hơn C ++).
Chris Halcrow

5
Cython biên dịch mã Python thành C để nó có thể được biên dịch thành một đối tượng chia sẻ.
greyfade

Phân biệt mã byte và mã máy theo kiểu này là khá tùy tiện. Java được biên dịch: trình biên dịch javac tạo ra các tệp lớp chứa các hướng dẫn mức thấp có thể được thực thi, trong máy ảo (ví dụ: hotspot) hoặc trực tiếp bằng phần cứng (ví dụ: trên bộ xử lý ARM có phần mở rộng Jazelle). Theo tôi biết, không có lý do kỹ thuật nào mà kiến ​​trúc bộ xử lý tương tự không thể được thiết kế để thực hiện trực tiếp các lệnh vm python.
Jules

@Jules Thật trùng hợp, mã Jython thực sự được biên dịch thành các tệp. Class mà tôi tin là được sử dụng lại cho đến khi bạn sửa đổi nguồn py.
JimmyJames

35

Python sẽ nằm dưới mã byte được giải thích. .pymã nguồn đầu tiên được biên dịch thành mã byte như .pyc. Mã byte này có thể được hiểu (CPython chính thức) hoặc JIT được biên dịch (PyPy). Mã nguồn Python ( .py) có thể được biên dịch thành các mã byte khác nhau như IronPython (.Net) hoặc Jython (JVM). Có nhiều triển khai ngôn ngữ Python. Một chính thức là một mã byte giải thích một. Có các mã triển khai JIT được biên dịch mã quá.

Để so sánh tốc độ của việc thực hiện các ngôn ngữ khác nhau, bạn có thể thử ở đây .


thanx cho thông tin. Theo các điểm chuẩn, hiệu suất của python giảm xuống!
crodjer

1
Liên kết tôi đã nêu rất rõ đây là những điểm chuẩn thiếu sót của việc triển khai ngôn ngữ . Python không nên là lựa chọn ngôn ngữ của bạn nếu bạn lo lắng quá nhiều về hiệu năng thực thi. Nếu bạn vẫn muốn so sánh, hãy so sánh các ngôn ngữ tương tự. Mã byte được giải thích CPython chính thức có thể so sánh hoặc nhanh hơn so với Ruby biên dịch JIT.
aufather

1
@ jase21 - "Kế hoạch của tôi trong năm 2006 là chuyển các kỹ thuật được triển khai trong Psyco sang PyPy. PyPy sẽ cho phép chúng tôi xây dựng một chuyên gia JIT linh hoạt hơn, dễ dàng thử nghiệm hơn và không cần phải đồng bộ hóa với các diễn biến của ngôn ngữ Python. " psyco.sourceforge.net/int sinhtion.html
igouy

1
@ jase21 - "làm cho mã python chạy nhanh hơn các bộ phận của bộ đếm C" - Chúng ta có nên dùng từ của bạn cho điều đó không?
igouy

3
Liên kết trong câu trả lời bị hỏng.
Basilevs

11

Biên dịch so với giải thích có thể hữu ích trong một số bối cảnh, nhưng khi áp dụng theo nghĩa kỹ thuật, đó là một sự phân đôi giả.

Một trình biên dịch (theo nghĩa rộng nhất) là một dịch giả . Nó dịch chương trình A sang chương trình B và để thực hiện trong tương lai, nó sử dụng máy M.

Một thông dịch viên (theo nghĩa rộng nhất) là một người thực thi . Đó là một máy M thực thi chương trình A. Mặc dù chúng ta thường loại trừ khỏi định nghĩa này các máy vật lý (hoặc các máy phi vật lý hoạt động giống như các máy vật lý). Nhưng từ góc độ lý thuyết, sự phân biệt đó có phần tùy ý.


Ví dụ, lấy re.compile. Nó "biên dịch" một biểu thức chính quy thành một hình thức trung gian và hình thức trung gian đó được diễn giải / đánh giá / thực thi.


Cuối cùng, nó phụ thuộc vào mức độ trừu tượng mà bạn đang nói đến, và những gì bạn quan tâm. Mọi người nói "biên dịch" hoặc "diễn giải" là những mô tả rộng rãi về những phần thú vị nhất của quy trình, nhưng thực sự hầu hết mọi chương trình đều được biên dịch (dịch) và diễn giải (thực hiện) theo cách này hay cách khác.

CPython (cách triển khai phổ biến nhất của ngôn ngữ Python) chủ yếu là thú vị để thực thi mã. Vì vậy, CPython thường sẽ được mô tả như được giải thích. Mặc dù đây là một nhãn lỏng lẻo.


7

Mã máy ảo là phiên bản nhỏ gọn hơn của mã nguồn gốc (mã byte). Nó vẫn cần được giải thích bởi một máy ảo, vì nó không phải là mã máy. Dù vậy, việc phân tích cú pháp dễ dàng và nhanh hơn so với mã gốc được viết bởi một con người.

Một số máy ảo tạo mã máy trong khi lần đầu tiên diễn giải mã máy ảo (chỉ trong quá trình biên dịch thời gian - JIT). Các lệnh sau đây sẽ sử dụng mã máy này trực tiếp, dẫn đến thực thi nhanh hơn.

Theo như tôi biết thì Ruby> = 1.9 cũng sử dụng một máy ảo như Python.


5

Thời gian chạy Python chạy mã đối tượng tùy chỉnh (mã byte) trên máy ảo.

Quá trình biên dịch chuyển đổi mã nguồn thành mã đối tượng.

Để tăng tốc mọi thứ, mã đối tượng (hoặc mã byte, nếu bạn thích) được lưu trữ trên đĩa, vì vậy nó có thể được sử dụng lại vào lần tiếp theo khi chương trình được chạy.

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.