Ví dụ về thời điểm chúng ta sẽ sử dụng ngôn ngữ được dịch qua ngôn ngữ được biên dịch?


11

Tôi hiểu sự khác biệt giữa ngôn ngữ được dịch và ngôn ngữ biên dịch, nhưng nếu ai đó có thể cung cấp một số ví dụ về tình huống khi người ta có thể sử dụng ngôn ngữ được dịch qua ngôn ngữ được biên dịch, cũng như tình huống khi người ta có thể sử dụng ngôn ngữ được biên dịch qua ngôn ngữ được dịch, thì đó là thực sự hữu ích

Câu trả lời:


11

Có (theo hiểu biết của tôi) không có thứ gọi là "ngôn ngữ" được giải thích hay "ngôn ngữ" được biên dịch.

Các ngôn ngữ xác định cú pháp và ý nghĩa của từ khóa, cấu trúc luồng và nhiều thứ khác, nhưng tôi biết rằng không có ngôn ngữ nào chỉ định liệu nó có phải được biên dịch hay diễn giải theo thông số ngôn ngữ hay không.

Bây giờ nếu bạn đặt câu hỏi là khi bạn sử dụng trình biên dịch ngôn ngữ so với trình thông dịch ngôn ngữ, thì nó thực sự thuộc về trình biên dịch của trình biên dịch so với trình thông dịch và mục đích của dự án.

Chẳng hạn, bạn có thể sử dụng trình biên dịch JRuby để tích hợp dễ dàng hơn với các thư viện java thay vì trình thông dịch ruby ​​MRI. Cũng có nhiều lý do để sử dụng trình thông dịch viên ruby ​​MRI trên JRuby, mặc dù tôi không quen với ngôn ngữ này và không thể nói điều này.

Lợi ích của người phiên dịch:

  • Không biên dịch nghĩa là thời gian từ chỉnh sửa mã đến kiểm tra ứng dụng có thể bị giảm bớt
  • Không cần tạo nhị phân cho nhiều kiến ​​trúc vì trình thông dịch sẽ quản lý trừu tượng hóa kiến ​​trúc (mặc dù bạn có thể vẫn phải lo lắng về các tập lệnh xử lý các kích thước nguyên một cách chính xác, không phải là phân phối nhị phân)

Lợi ích của trình biên dịch:

  • Mã gốc được biên dịch không có chi phí hoạt động của trình thông dịch và do đó thường hiệu quả hơn về thời gian và không gian
  • Khả năng tương tác thường tốt hơn, cách duy nhất để tương tác in-Proc với các tập lệnh là thông qua một trình thông dịch chứ không phải là một FFI tiêu chuẩn
  • Khả năng hỗ trợ kiến ​​trúc trình thông dịch chưa được biên dịch cho (chẳng hạn như các hệ thống nhúng)

Tuy nhiên, tôi sẽ đặt cược trong 90% trường hợp nó diễn ra giống như thế này: tôi muốn viết phần mềm này trong blub vì tôi biết nó tốt và nó nên làm tốt công việc. Tôi sẽ sử dụng trình thông dịch blub (hoặc trình biên dịch) bởi vì đây là phương pháp chính tắc được chấp nhận chung để viết phần mềm trong blub.

Vì vậy, TL, DR về cơ bản, trong từng trường hợp so sánh cơ sở của trình thông dịch so với trình biên dịch cho trường hợp sử dụng cụ thể của bạn.

Ngoài ra, FFI: Giao diện chức năng nước ngoài, nói cách khác là giao diện để tương tác với các ngôn ngữ khác. Đọc thêm tại wikipedia


2
Theo hiểu biết của tôi, một số ngôn ngữ kịch bản cho HĐH như ksh cho UNIX không thể được biên dịch.
NoChance

@delnan, quan điểm của tôi là không thể được biên dịch thông qua một phần mềm thương mại hoặc miễn phí mà tôi biết, không phải là nó không thể được biên dịch vì lý do kỹ thuật.
NoChance

3
@EmmadKareem Không có thứ gọi là "không thể biên dịch". Bạn viết một chương trình đọc một chương trình bằng ngôn ngữ Li và xuất ra một chương trình tương đương bằng ngôn ngữ La. Đó là trình biên dịch một trình biên dịch. Tôi ngần ngại gọi ra đối số đầy đủ của Turing vì đây là một cá trích đỏ trong thực tế, nhưng mỗi chương trình cuối cùng biến thành một chuỗi các hướng dẫn mã máy. Nếu vẫn thất bại, hãy hủy vòng lặp trình thông dịch (và đơn giản hóa mã kết quả để loại bỏ các phần bạn không cần nữa). Nếu trình thông dịch được viết bằng ngôn ngữ không có trình thông dịch, hãy lặp lại cho đến khi bạn nhấn một cái gì đó với trình biên dịch.

1
. Nhưng tôi không thấy làm thế nào điều này có liên quan. Luôn luôn có thể và khả thi để làm như vậy và có thể được thực hiện bất cứ lúc nào với một số nỗ lực. Đây là một hệ quả của điểm chính, đó là một ngôn ngữ không được biên dịch hay giải thích và có thể được thực hiện theo cả hai cách. Và trong vô số cách khác (tốt, có thể nói là các biến thể nhỏ và phối lại), nhân tiện.

2
@EmmadKareem nếu bạn muốn, bạn có thể lấy thông số ngôn ngữ ksh và viết một trình biên dịch đọc nó và tạo một nhị phân riêng. Ngôn ngữ được biên dịch hoặc giải thích không theo định nghĩa của ngôn ngữ là quan điểm của tôi ở đây.
Jimmy Hoffa

8

Một điểm quan trọng ở đây là nhiều triển khai ngôn ngữ thực sự làm một số loại lai của cả hai. Nhiều ngôn ngữ thường được sử dụng ngày nay hoạt động bằng cách biên dịch một chương trình thành một định dạng trung gian như mã byte, và sau đó thực hiện nó trong một trình thông dịch. Đây là cách Java, C #, Python, Ruby và Lua thường được triển khai. Trong thực tế, điều này được cho là cách mà hầu hết các ngôn ngữ được sử dụng ngày nay được thực hiện. Vì vậy, thực tế là, ngôn ngữ ngày nay vừa diễn giải vừa biên dịch mã của họ. Một số ngôn ngữ này có trình biên dịch JIT bổ sung để chuyển đổi mã byte thành mã gốc để thực thi.

Theo tôi, chúng ta nên ngừng nói về các ngôn ngữ được giải thích và biên dịch bởi vì chúng không còn là phạm trù hữu ích để phân biệt sự phức tạp của việc triển khai ngôn ngữ ngày nay.

Khi bạn hỏi về giá trị của các ngôn ngữ được dịch và biên dịch, bạn có thể có ý nghĩa khác. Bạn có thể hỏi về giá trị của việc gõ tĩnh / động, giá trị của việc phân phối các tệp thực thi gốc, các lợi thế tương đối của quá trình biên dịch JIT và AOT. Đây là tất cả các vấn đề được kết hợp với giải thích / biên dịch nhưng là các vấn đề khác nhau.


2

Trước hết, một ngôn ngữ lập trình có thể được suy ra và biên dịch. Giải thích và biên dịch chỉ là phương pháp tạo mã thực thi từ mã nguồn. Với một trình thông dịch, mã nguồn đang được đọc và giải thích bởi một trình thông dịch, sau đó thực thi mã khi nó diễn giải nó. Mặt khác, trình biên dịch đọc mã nguồn và tạo tệp nhị phân thực thi từ mã nguồn - để chương trình có thể được chạy như một quy trình riêng biệt một cách độc lập.

Bây giờ trước khi bất cứ ai thắc mắc ... Có, C / C ++ / C # / Java có thể được diễn giải và có, các tập lệnh JavaScript và Bash có thể được biên dịch. Cho dù có phiên dịch làm việc hoặc trình biên dịch cho các ngôn ngữ này là một câu hỏi khác mặc dù.

Bây giờ để thực sự trả lời câu hỏi khi chúng ta sử dụng "ngôn ngữ được giải thích" trên "ngôn ngữ được biên dịch". Bản thân câu hỏi hơi khó hiểu, nhưng tôi cho rằng nó có nghĩa là khi nào thích diễn giải hơn biên soạn. Một trong những nhược điểm của quá trình biên dịch là nó tạo ra một số chi phí do quá trình biên dịch - mã nguồn phải được biên dịch thành mã máy thực thi để không phù hợp với các tác vụ yêu cầu độ trễ tối thiểu khi gọi mã nguồn để thực thi chương trình. Mặt khác, mã nguồn được biên dịch hầu như luôn luôn nhanh hơn mã nguồn được giải thích tương đương do chi phí gây ra bởi việc diễn giải mã. Mặt khác, thông dịch viên có thể gọi và chạy mã nguồn với rất ít chi phí gọi, nhưng với chi phí thực hiện thời gian chạy.

Cuối cùng, gần như không thể đề cập đến bất kỳ trường hợp sử dụng xác định nào khi thích cái này hơn cái khác, nhưng ví dụ một trường hợp (với trường hợp rất không thực tế của tôi) sẽ là khi mã nguồn chương trình thay đổi linh hoạt giữa các yêu cầu chương trình và quá trình biên dịch quá cao cho nó là sự lựa chọn khả thi. Trong trường hợp đó, việc giải thích mã nguồn thay vì biên dịch có lẽ là điều mong muốn.

Tuy nhiên, có một thứ có thể được coi là một ví dụ trong thế giới thực: mã nguồn hidnig khi triển khai. Với nguyên bảnmã được biên dịch, nhà phát triển triển khai mã macine thực thi của chương trình và dữ liệu. Với mã được giải thích, chính mã nguồn phải được triển khai, sau đó có thể được kiểm tra và thiết kế ngược với nỗ lực ít hơn nhiều so với mã máy kỹ sư đảo ngược. Một ngoại lệ cho điều này là các ngôn ngữ như C # và Java sẽ biên dịch thành ngôn ngữ / mã byte ngay lập tức (MSIL cho C # và mã byte Java cho Java) sau đó được triển khai và biên dịch "ngay lúc đó", giống như một trình thông dịch. Tuy nhiên, tồn tại cái gọi là bộ dịch ngược cho MSIL và Java Bytecode, có thể tái tạo lại mã nguồn gốc với độ chính xác tương đối tốt và do đó các sản phẩm kỹ thuật đảo ngược như vậy tầm thường hơn nhiều so với các sản phẩm kỹ thuật đảo ngược được triển khai trong mã máy gốc.


1
Bạn làm cho điểm tốt, nhưng tôi là người dạy dỗ, tôi có vấn đề với một số cụm từ (cả hai đều đề cập đến đoạn thứ ba): 1. Một thông dịch viên không biên dịch. 2. Có thể hiểu được (mặc dù những điều kiện này rất hiếm) khi trình biên dịch không tối ưu hóa xấu bị đánh bại bởi trình thông dịch được tối ưu hóa cao (đặc biệt là dựa trên mã byte). Điều này sẽ tăng gấp đôi nếu bạn tính các trình biên dịch JIT theo thông dịch viên (điều mà tôi không muốn làm, nhưng một số người làm điều đó).

@delnan Có lẽ nó nói xấu, tôi không phải là người nói tiếng Anh bản ngữ. Tuy nhiên, theo như tôi có thể nói đoạn thứ ba không ngụ ý rằng một thông dịch viên sẽ biên dịch. Đối với điểm thứ hai, tôi nhấn mạnh vào từ tương đương với sự tương tự nhấn mạnh của mã được biên dịch và giải thích để loại trừ các trường hợp trình biên dịch kém so với trình thông dịch hiệu suất cao, có lẽ tôi đã không rõ ràng với nó, tuy nhiên tôi không thấy nó hợp lý để tập trung vào giải thích các trường hợp cực đoan như vậy vì nó không đóng góp gì cho điểm được tạo ra giữa sự khác biệt của việc thực thi mã nguồn bằng cách biên dịch hoặc lặp lại nó
zxcdw

Xin lỗi, không bao giờ điểm đầu tiên, tôi đọc sai một cái gì đó. Mea culpa. Về điểm thứ hai: Tôi lấy "tương đương" để chỉ mã được diễn giải hoặc biên dịch (và so sánh trình biên dịch và trình thông dịch không có nhiều ý nghĩa, vì chúng làm những việc khác nhau cơ bản). Tôi không nghĩ người ta nên lãng phí thời gian để nêu chi tiết các trường hợp kỳ quặc như ví dụ của tôi, nhưng tôi thích bỏ "luôn luôn" để giải thích lý do tại sao thể nhanh hơn ở nơi đầu tiên: Không cần thông dịch viên đã xác định IMHO] và cơ hội để thực hiện tối ưu hóa trước khi chạy.

1

Tôi có thể nghĩ về các tình huống sau đây khi bạn sử dụng ngôn ngữ được diễn giải :

  • Trường hợp không có trình biên dịch tồn tại, như tập lệnh shell Linux / Unix .
  • Kịch bản nhanh và bẩn giải quyết một vấn đề nhỏ
  • Các ngôn ngữ giúp dễ dàng viết các trang HTML động và được diễn giải rộng rãi như JSP (Tomcat biên dịch nó thành một trình quản lý phổ biến để chạy), PHP, ASP, v.v.

Tôi có thể nghĩ về các tình huống sau đây khi bạn muốn biên dịch mã của mình:

  • Bạn cần phân phối nhị phân vì ứng dụng của bạn là nguồn đóng và bạn không muốn cung cấp mã nguồn của mình.
  • Tốc độ, như hệ thống nhúng và tương tự.
  • Bạn cần một mức độ an toàn loại mã mà chỉ một trình biên dịch với ngôn ngữ được gõ đúng có thể cung cấp cho bạn. Trình biên dịch hiển thị lỗi chính tả trong mọi ngóc ngách của mã nguồn của bạn, trong khi đó, trong các chương trình được giải thích, lỗi chính tả có thể không được phát hiện thành mã sản xuất.
  • Các hệ thống lớn , phức tạp: không thể tưởng tượng một hệ điều hành hoặc một bộ đồ công sở như bất cứ thứ gì ngoại trừ các tệp nhị phân được biên dịch.
  • Bạn muốn giải quyết mọi vấn đề nhỏ nhặt và cần giao tiếp tốt với các đoạn mã biên dịch (khó với bất kỳ loại thời gian chạy nào, đặc biệt là với trình thông dịch) (điểm này được đưa ra bởi một nhận xét @delnam)

3
Một thông dịch viên ngôn ngữ làm cho ngôn ngữ không kém phần mạnh mẽ. Haskell được gõ rất mạnh và bạn có thể sử dụng GHCI để diễn giải nó một cách hiệu quả. Gõ mạnh / yếu là các khía cạnh của ngôn ngữ, không phải là các khía cạnh của trình biên dịch hoặc trình thông dịch.
Jimmy Hoffa

1
-1 Về ưu điểm biên dịch: (1) Mã biên dịch không bảo vệ chống lại kỹ thuật đảo ngược, nó chỉ làm cho nó khó hơn một chút. (2) Biên dịch (loại bỏ chi phí phiên dịch, tối ưu hóa mã ứng dụng tự động) chỉ là một nguồn hiệu suất và được vượt qua bởi tối ưu hóa quy mô lớn được thực hiện bằng tay bởi một chuyên gia về con người. (3) Kiểm tra kiểu, trong khi thường được kết hợp với biên dịch, độc lập với nó. Một trình kiểm tra loại là một phân tích tĩnh; nó có thể xảy ra mà không cần phát ra mã và trước khi diễn giải mã. (4) Có vẻ khá giả. Bạn "không thể tưởng tượng" điều đó? Tại sao? Yêu cầu như thế nào?

1
Các ngôn ngữ thông dịch khác tồn tại bất cứ khi nào có một thông dịch viên trong một chương trình khác. Bất cứ khi nào một người đang sử dụng mẫu trình thông dịch , có một ngôn ngữ được diễn giải có độ phức tạp.

3
"Kịch bản" không nhất thiết phải được giải thích. Nhiều ngôn ngữ "scripting" được biên dịch thành mã byte cho một máy ảo sau đó được thực thi (xem lua, perl, python, ruby). Không có sự khác biệt thực sự giữa cái này và java ngoài việc biên dịch diễn ra.

3
+1, tôi nghĩ đó là loại câu trả lời của OP thực sự sau đó, và mặc dù các điểm có thể không đúng 100% như đã chỉ ra, có ít nhất 95% đúng cho những cân nhắc thực tế.
Doc Brown

1

Cuối cùng, sự đánh đổi lớn nằm giữa năng suất (bạn phải viết bao nhiêu dòng mã) và hiệu suất (chương trình của bạn sẽ thực thi nhanh như thế nào).

Vì các ngôn ngữ được giải thích khi chuyển đổi thành thông tin CPU có nhiều thông tin hơn, chúng có thể dựa vào phản xạ và gõ động giúp tăng năng suất rất nhiều . Một ưu điểm khác của ngôn ngữ thông dịch là chúng độc lập với nền tảng nên từ lâu đã có trình thông dịch cho nền tảng.

Bởi vì CPU không được chuyển đổi mã ngôn ngữ trong mã máy và chạy mã cùng một lúc, như trong trường hợp được giải thích, các ngôn ngữ được biên dịch mang lại các chương trình nhanh hơn. Ngoài ra, một hệ thống được xây dựng bằng ngôn ngữ được biên dịch sẽ an toàn hơn vì nó có thể phát hiện các sự cố tại thời gian biên dịch, điều đó có nghĩa là bạn gặp lỗi khi bạn nhập nó (với các IDE hiện đại) thay vì chỉ nhìn thấy khi bạn thực sự chạy chương trình (tất nhiên , điều này không sửa lỗi logic).

Biết điều này, các ngôn ngữ được giải thích phù hợp cho:

  1. Phát triển năng suất: phát triển web nhanh (PHP, Javascript) hoặc để tạo mẫu.
  2. Đa nền tảng; ví dụ JavaScript được hỗ trợ trong mọi trình duyệt (bao gồm cả trình duyệt di động).

Và các ngôn ngữ được biên dịch phù hợp khi:

  1. Hiệu suất là rất quan trọng (hệ điều hành) hoặc tài nguyên đang khan hiếm (vi điều khiển).
  2. Các hệ thống được xây dựng rất phức tạp; khi xây dựng các hệ thống lớn (hệ thống doanh nghiệp) các ngôn ngữ được biên dịch là xử lý thiết yếu nhiều lỗi có thể xuất hiện trong các ngôn ngữ được giải thích; các chương trình phức tạp cũng đòi hỏi nhiều tài nguyên và sự cân bằng cũng có xu hướng biên dịch các ngôn ngữ.

-1 bởi vì bạn ngụ ý rằng tất cả các ngôn ngữ được dịch đều được gõ động và tất cả các ngôn ngữ được biên dịch đều được nhập tĩnh, điều này hoàn toàn sai.
Daniel Pryden

@DanielPryden Đó phải là sự trùng hợp thuần túy sau đó, thực tế là hầu hết tất cả các ngôn ngữ được giải thích đều được gõ động và những ngôn ngữ được biên dịch được gõ tĩnh? Có phải là một sự trùng hợp ngẫu nhiên khi mô hình kiểu động phù hợp với các ngôn ngữ được giải thích?
m3th0dman

Vì nhiều lý do, có một mối tương quan, nhưng đó không phải là một yêu cầu. Điều này thực sự đã được hỏi trên StackOverflow: Tại sao các lang được giải thích chủ yếu là vịt trong khi được biên dịch có kiểu gõ mạnh?
Daniel Pryden

1
Erlang được biên dịch và gõ động. Haskell được gõ tĩnh và có thể được biên dịch hoặc giải thích
Zachary K

1
@ZacharyK Erlang có hệ thống thời gian chạy; Haskell được biên soạn trong phần lớn các trường hợp (chương trình được viết).
m3th0dman

1

Bên cạnh những lý do mà những người khác đã đề cập, có một trường hợp sử dụng đặc biệt quan trọng để chọn cách giải thích đặc biệt cho bất kỳ hình thức biên dịch hoặc bất kỳ phương pháp lai nào.

Trong trường hợp nếu một ngôn ngữ lập trình được sử dụng như một giao thức giao tiếp và khi độ trễ phản hồi là quan trọng, thì sẽ tốt hơn để tránh lãng phí thời gian vào việc biên dịch và bất kỳ quá trình tiền xử lý nào có thể.

Điều này áp dụng cho các ngôn ngữ đại lý, ví dụ, hoặc cho cách thức, nói, Tcl / Tk thường được sử dụng.

Một lý do có thể khác để gắn bó với phiên dịch là khi trình thông dịch ngôn ngữ được sử dụng để tự khởi động hoặc ngôn ngữ cấp cao hơn, phức tạp hơn và tính đơn giản của nó quan trọng hơn hiệu suất của quá trình bootstrap.

Đối với gần như bất kỳ trường hợp sử dụng có thể khác, biên dịch (hoặc một phương pháp lai) là phù hợp hơn.

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.