2009-05-20 19 views

Trả lời

33

Gần như không có thông dịch viên thực sự diễn giải mã số trực tiếp, từng dòng - nó đơn giản là không hiệu quả. Hầu như tất cả các phiên dịch đều sử dụng một số biểu diễn trung gian có thể được thực thi dễ dàng. Ngoài ra, tối ưu hóa nhỏ có thể được thực hiện trên mã trung gian này.

Python tiếp tục lưu trữ mã này có lợi thế rất lớn cho lần tiếp theo mã này được thực hiện: Python không phải phân tích mã nữa; phân tích cú pháp là phần chậm nhất trong quá trình biên dịch. Vì vậy, một biểu diễn bytecode giảm chi phí thực thi khá đáng kể.

+1

Ngay cả MS BASIC cũ trên TRS-80 của tôi đã sử dụng lược đồ mã hóa rất đơn giản: ngay khi tôi nhập hoặc chỉnh sửa một dòng, từ khóa BASIC đã bị thu gọn thành các byte đơn. –

+1

@DavidThornley: Nhiều máy tính của 1980 sử dụng một dẫn xuất của MS-basic đã chuyển đổi từ khóa thành mã thông báo, nhưng giữ số và tên biến ở dạng văn bản, do đó phải tính toán giá trị của chúng hoặc tìm kiếm chúng khi chạy. Atari BASIC đã xử lý nhiều hơn, xây dựng một bảng các biến và thay thế tên của chúng bằng các chỉ số. Nó cũng chuyển đổi số sang số BCD dấu phẩy động. Chỉ chuỗi ký tự và chú thích chuỗi được lưu dưới dạng văn bản. Những thứ như vậy có thể đã cho phép Atari BASIC hoạt động tốt hơn số khác, ngoại trừ số của mỗi dòng được lưu trữ dưới dạng nhị phân, nhưng mục tiêu GOTO ... – supercat

+1

... được lưu trữ dưới dạng dấu phẩy động BCD, vì vậy mọi GOTO đều yêu cầu chuyển đổi BCD thành nhị phân . Tuy nhiên, điều thú vị là tác giả của Atari BASIC đã chuyển đổi chương trình thành một biểu diễn được phân tích cú pháp thay vì chỉ thay thế các từ khóa bằng mã thông báo. – supercat

7

Vì việc giải thích trực tiếp từ bytecode nhanh hơn. Nó tránh sự cần thiết phải làm lexing, cho một điều.

8

Vì bạn có thể biên dịch thành .pyc một lần và diễn giải nó nhiều lần.

Vì vậy, nếu bạn đang chạy tập lệnh nhiều lần, bạn chỉ có chi phí phân tích mã nguồn một lần.

6

Lặp lại và phân tích cú pháp mã nguồn nhiều lần, thay vì thực hiện nó một lần (thường xuyên nhất trên import), rõ ràng sẽ là một sự lãng phí ngớ ngẩn và vô nghĩa.

+0

Chỉ cần chạy một tập tin ".py" không dẫn đến tái lexing và phân tích cú pháp mã nguồn hơn và hơn, phải không? Nếu tệp lớn, đây có thể là một chi phí đáng kể. Tôi không chắc tại sao nhập khẩu lại được điều trị đặc biệt. Tôi thực sự đánh giá cao sự giúp đỡ nào trong sự hiểu biết. – batbrat

-1

Tôi nghi ngờ rất nhiều rằng lý do là hiệu suất, mặc dù nó là một hiệu ứng phụ tốt đẹp. Tôi sẽ nói rằng nó chỉ là tự nhiên để nghĩ rằng một máy ảo được xây dựng xung quanh một số ngôn ngữ lắp ráp cao cấp sẽ thực tế hơn là tìm và thay thế văn bản trong một số chuỗi mã nguồn.

Edit:

Được rồi, rõ ràng, đã từng đặt một -1 bỏ phiếu về bài đăng của tôi mà không để lại một lời nhận xét hợp lý để giải thích biết rất ít về máy ảo (run-time môi trường).

http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Erik-Meijer-and-Lars-Bak-Inside-V8-A-Javascript-Virtual-Machine/

+1

Tôi đã không -1, nhưng tôi sẽ thành thật mà tôi không hiểu điểm của bạn, đặc biệt là phần này: "sẽ thực tế hơn là tìm và thay thế văn bản trong một số chuỗi mã nguồn" –

+0

Xem video trên kênh 9, hoặc viết máy ảo của riêng bạn, hoặc cả hai có lẽ sẽ giải thích toàn bộ quá trình chi tiết cho bạn. Những gì tôi có nghĩa là bởi báo giá đó là đôi khi nó dễ dàng hơn để thực hiện tối ưu hóa trên một mức độ trừu tượng cao hơn so với lắp ráp. Khi bạn làm điều này bình thường bạn làm việc với một AST (cây cú pháp trừu tượng), nếu bạn không có, bạn vẫn có thể thực hiện các tối ưu hóa tương tự nhưng chúng phải di chuyển mã nguồn xung quanh, tức là tìm và thay thế. có xu hướng đi với đại diện trung gian khác vì lý do này (xem mã ba địa chỉ). –

+0

Mã byte chỉ là một biểu diễn nhỏ gọn và thực tế hiệu quả hơn của AST. –

2

Mặc dù có một khía cạnh hiệu quả nhỏ để nó (bạn có thể lưu trữ các bytecode trên đĩa hoặc trong bộ nhớ), chủ yếu là kỹ thuật của nó: nó cho phép bạn tách phân tích cú pháp từ giải thích. Phân tích cú pháp thường có thể là những sinh vật khó chịu, đầy đủ các trường hợp cạnh tranh và phải tuân theo các quy tắc bí truyền như chỉ sử dụng đúng số lượng lookahead và giải quyết các vấn đề về shift-reduce. Ngược lại, việc diễn dịch rất đơn giản: nó chỉ là một câu lệnh chuyển đổi lớn sử dụng mã opcode của bytecode.

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