Tại sao Python cần cả trình biên dịch và trình thông dịch?


9

Tôi có thể hiểu thực tế rằng Java cần cả trình biên dịch và trình thông dịch. Nó biên dịch mã nguồn thành mã byte và sau đó là một máy ảo (trên Windows, trên Linux, trên Android, v.v.) dịch mã byte đó thành mã máy cho kiến ​​trúc hiện tại.

Nhưng tại sao Python cần cả trình biên dịch và trình thông dịch? Vì Python không độc lập với nền tảng, tại sao không sử dụng giải thích? Theo như tôi biết, bạn không thể thực thi chương trình Python (được biên dịch thành mã byte) trên bất kỳ máy Windows hoặc Linux nào mà không sửa đổi. Hoặc là tôi sai?


Bạn có thể sai. Nếu sử dụng Lua thay vì Python, bạn sẽ sai.
Basile Starynkevitch 11/07/2015

Câu trả lời:


13

Theo như tôi biết, bạn không thể thực thi chương trình Python (được biên dịch thành mã byte) trên mọi máy, chẳng hạn như trên windows hoặc trên linux mà không cần sửa đổi.

Bạn không chính xác. Mã byte python là nền tảng chéo. Xem Có phải python bytecode phụ thuộc phiên bản không? Có phụ thuộc vào nền tảng? trên Stack Overflow. Tuy nhiên, nó không tương thích giữa các phiên bản. Python 2.6 không thể thực thi các tệp Python 2.5. Vì vậy, trong khi đa nền tảng, nó thường không hữu ích như một định dạng phân phối.

Nhưng tại sao Python cần cả trình biên dịch và trình thông dịch?

Tốc độ. Giải thích nghiêm ngặt là chậm. Hầu như mọi ngôn ngữ "được giải thích" thực sự biên dịch mã nguồn thành một loại biểu diễn bên trong để nó không phải phân tích cú pháp liên tục. Trong trường hợp của python, nó lưu biểu diễn bên trong này vào đĩa để nó có thể bỏ qua quá trình phân tích cú pháp / biên dịch vào lần tới khi nó cần mã.


7

Tôi có thể hiểu thực tế rằng Java cần cả trình biên dịch và trình thông dịch.

Nó không. Không có gì trong Đặc tả ngôn ngữ Java nói rằng Java cần phải có trình biên dịch. Cũng không có gì trong Đặc tả ngôn ngữ Java nói rằng Java cần phải có trình thông dịch.

Việc sử dụng trình thông dịch, trình biên dịch hay kết hợp cả hai, hoàn toàn tùy thuộc vào người thực hiện.

Trong thực tế, có các triển khai Java biên dịch thẳng vào mã máy, ví dụ Trình biên dịch GNU cho Java gcj. Về mặt kỹ thuật, trình biên dịch Java OpenJDK cũng biên dịch thành mã máy, cụ thể là mã byte JVM. Bây giờ, bạn có thể nói, đợi một chút, đó không phải là mã máy! Nhưng, có các trình thông dịch phần mềm cho mã máy x86 và có các CPU phần cứng có thể thực thi mã byte JVM, vậy điều gì làm cho một "bản địa" còn cái kia thì không?

Lưu ý rằng mã byte JVM nằm ngoài Đặc tả ngôn ngữ Java, giống như mã máy x86.

và sau đó một máy ảo (trên Windows, trên Linux, trên Android, v.v.) dịch mã byte đó thành mã máy cho kiến ​​trúc hiện tại.

Một lần nữa, đó là hoàn toàn tùy thuộc vào người thực hiện.

Sun JVM ban đầu không bao giờ dịch, nó luôn luôn diễn giải. Các trình thông dịch JVM của Oracle OpenJDK hiện tại và chỉ những phần được thực thi thường được biên dịch. Maxine Research VM luôn biên dịch JIT. Việc triển khai Excelsior.JET biên dịch một lần, trước thời hạn. JVM IKVM.NET biên dịch thành mã byte CIL. Android Runtime biên dịch trước thời gian, một lần, trong khi cài đặt. (Ngoài ra, Android Runtime không hiểu mã byte JVM, nó sử dụng mã byte Dalvik, một ngôn ngữ hoàn toàn khác.)

Nhưng tại sao Python cần cả trình biên dịch và trình thông dịch?

Một lần nữa, nó không. Không có gì trong Đặc tả ngôn ngữ Python nói rằng Python cần phải có trình biên dịch. Cũng không có gì trong Đặc tả ngôn ngữ Python nói rằng Python cần phải có trình thông dịch.

Lưu ý rằng thực sự, Python không bao giờ được giải thích. Tất cả các cài đặt Python hiện có luôn biên dịch Python sang một ngôn ngữ khác. Lần lượt, ngôn ngữ đó có thể hoặc không, được dịch, nhưng ngôn ngữ đó là ngôn ngữ khác với Python. Python không được giải thích.

Tại sao không chỉ sử dụng giải thích?

Bởi vì Python không được thiết kế để có thể dễ dàng giải thích bằng máy. Nó được thiết kế để dễ dàng được giải thích bởi con người. OTOH, mã byte CPython, được thiết kế để dễ dàng diễn giải bằng máy. Vì vậy, thật hợp lý khi viết mã bằng ngôn ngữ được thiết kế cho con người và diễn giải bằng ngôn ngữ được thiết kế cho máy móc, và để có được từ cái này sang cái khác, bạn phải biên dịch.

Theo như tôi biết, bạn không thể thực thi chương trình Python (được biên dịch thành mã byte) trên bất kỳ máy Windows hoặc Linux nào mà không sửa đổi.

Vâng, bạn có thể. Máy ảo CPython có sẵn cho cả Windows và Linux, cũng như PyPy, Jython và IronPython.


Ngôn ngữ không phải được biên dịch hoặc giải thích. Ngôn ngữ chỉ . Trong thực tế, một ngôn ngữ hoàn toàn có thể tồn tại mà không cần bất kỳ trình thông dịch hoặc trình biên dịch! Ví dụ, Plankalkül của Konrad Zuse mà ông thiết kế vào những năm 1930 không bao giờ được thực hiện trong suốt cuộc đời của ông. Bạn vẫn có thể viết các chương trình trong đó, bạn có thể phân tích các chương trình đó, lý do về chúng, chứng minh các thuộc tính về chúng. Bạn không thể thực hiện chúng. (Chà, thực ra, thậm chí điều đó là sai: tất nhiên bạn có thể chạy chúng trong đầu hoặc bằng bút và giấy.)

Bây giờ, bất kỳ triển khai cụ thể nào của ngôn ngữ đều có thể sử dụng trình biên dịch (hoặc thậm chí nhiều trình biên dịch), trình thông dịch hoặc bất kỳ kết hợp nào. Nhưng đó là một đặc điểm của việc thực hiện , không phải ngôn ngữ. Mọi ngôn ngữ đều có thể được thực hiện với trình biên dịch và mọi ngôn ngữ đều có thể được thực hiện với trình thông dịch.

Tuy nhiên, lưu ý rằng bạn không thể chạy chương trình mà không có trình thông dịch. Một trình biên dịch chỉ đơn giản là dịch một chương trình từ ngôn ngữ này sang ngôn ngữ khác. Nhưng kia là nó. Bây giờ bạn có cùng một chương trình, chỉ bằng một ngôn ngữ khác. Cách duy nhất để thực sự có được kết quả của chương trình là diễn giải nó. Đôi khi, ngôn ngữ là ngôn ngữ máy nhị phân cực kỳ đơn giản và trình thông dịch thực sự được mã hóa bằng silicone (và chúng tôi gọi nó là "CPU"), nhưng đó vẫn là phiên dịch.

Bạn cũng có thể quan tâm đến câu trả lời này của tôi, nó giải thích sự khác biệt và các phương tiện kết hợp trình thông dịch, trình biên dịch JIT và trình biên dịch AOT khác nhaucâu trả lời này liên quan đến sự khác biệt giữa trình biên dịch AOT và trình biên dịch JIT .


3
Những câu trả lời dành phần lớn thời gian của họ là mang tính mô phạm thay vì trả lời câu hỏi khiến tôi buồn.
Winston Ewert

3

Đúng là mã byte không phù hợp làm định dạng phân phối, nhưng điều đó không có nghĩa là nó vô dụng. Ngoài việc cải thiện thời gian khởi động trên một máy nhất định, sau lần chạy đầu tiên, việc giải thích mã byte cũng đơn giản hơn nhiều so với việc giải thích AST hoặc, không được phép, diễn giải từng dòng một.

Bytecode là một đại diện cấp thấp hơn, thường xuyên hơn, gọn hơn (cả về mặt ngữ nghĩa và về mặt bố trí bộ nhớ) của mã. Thứ tự của các hoạt động đã được đánh vần, tên biến cục bộ đã được giải quyết thành một hình thức đơn giản hơn (chỉ số nguyên). Không có cú pháp phức tạp để làm theo, chỉ cần một hướng dẫn đơn giản sau một hướng dẫn khác. Ngoài ra, cần ít trạng thái hơn: đối với phiên dịch từng dòng, về cơ bản bạn cần phải giữ toàn bộ trình phân tích cú pháp và trình thông dịch AST làm nổ tung ngăn xếp cuộc gọi với giao dịch cây của nó, trong khi đó, trình thông dịch mã byte chỉ cần một ngăn xếp nhỏ cho các giá trị tạm thời và người dân địa phương.

Những yếu tố này và các yếu tố khác âm mưu làm cho trình thông dịch mã byte nhanh hơn đáng kể so với các trình thông dịch khác.

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.