编译和解释有什么区别? [英] What is the difference between compilation and interpretation?

查看:15
本文介绍了编译和解释有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚与一位同事进行了一次对话,并在那里谈论了 V8 JavaScript 引擎.根据维基百科,

I just had a conversation with a colleague and where were talking about the V8 JavaScript engine. According to Wikipedia,

V8 在执行之前将 JavaScript 编译为原生机器码 [...],而不是更传统的技术,例如解释字节码或将整个程序编译为机器码并从文件系统执行.

V8 compiles JavaScript to native machine code [...] before executing it, instead of more traditional techniques such as interpreting bytecode or compiling the whole program to machine code and executing it from a filesystem.

where(如果我错了,请纠正我)解释字节码"是 Java 的工作方式,而编译整个程序"将适用于像 C 这样的语言或 C++.现在我们想知道、辩论和提出关于差异和相似性的错误断言和假设.为此,我建议咨询 SO 专家.

where (correct me if I'm wrong) "interpreting bytecode" is the way Java works, and "compiling the whole program" would apply for languages like C or C++. Now we were wondering, debating and posing false assertions and presumptions about differences, similarities. To end this, I recommended asking the experts on SO.

那么,谁能做到

  1. 命名、解释和/或引用所有主要方法(例如预编译与运行时解释)
  2. 可视化或提供有关来源、编译和解释之间关系的方案
  3. 为#1 的主要方法举例(命名编程语言).

<小时>

注意事项:


Notes:

  • 我不是在寻找关于不同范式的冗长乏味的文章,而是在寻找具有视觉支持的快速概述.
  • 我知道 Stackoverflow 并不是程序员的百科全书(而是用于解决更具体问题的问答平台).但是由于我可以找到很多流行的问题,因此可以为某些主题提供百科全书式的视图(例如 [1], [2][3][4], [5]),我开始提出这个问题.
  • 如果此问题更适合任何其他 StackExchange 站点(例如 cstheory),请告诉我或标记此问题以供审核.
  • I am not looking for a long prosaic essay about the different paradigms, but an visually supported, quick overview.
  • I know that Stackoverflow is not intended to be a encyclopedia for programmers (but rather a Q&A platform for more specific questions). But since I can find a lot of popular questions, that kind of provide an encyclopedic view to certain topics (e.g. [1], [2], [3], [4], [5]), I started this question.
  • If this question would rather fit into any other StackExchange site (e.g. cstheory), please let me know or flag this question for moderation.

推荐答案

几乎不可能回答您的问题,原因很简单:没有几种方法,它们是一个连续体.在这个连续体中涉及的实际代码也相当相同,唯一的区别是事情发生的时间,以及是否以某种方式保存了中间步骤.在这个连续体中的各个点(它不是一条线,一个进展,而是更多的具有不同角的矩形,您可以靠近)是:

It's near-impossible to answer your question for one simple reason: There aren't a few approaches, they are rather a continuum. The actual code involved across this continuum is also fairly identical, the only difference being when things happen, and whether intermediate steps are saved in some way or not. Various points across this continuum (which is not a single line, a progression, but rather more of a rectangle with different corners to which you can be close) are:

  1. 阅读源代码
  2. 理解代码
  3. 执行你所理解的
  4. 缓存沿途的各种中间数据,甚至将它们持久保存到磁盘.

例如,一个纯粹的解释编程语言几乎不会做#4 和#2 有点隐含地发生在 1 和 3 之间,所以你几乎不会注意到它.它只是读取代码的一部分,并立即对它们做出反应.这意味着实际开始执行的开销很低,但是例如在循环中,相同的文本行被读取并再次重新读取.

For example, a purely interpreted programming language Pretty much doesn't do #4 and #2 kinda happens implicitly between 1 and 3 so you'd barely notice it. It just reads sections of the code, and immediately reacts to them. This means there is low overhead to actually starting execution, but e.g. in a loop the same lines of text get read and re-read again.

在矩形的另一个角落,有传统的编译语言,其中第 4 项通常包括将实际机器代码永久保存到文件中,然后可以在以后运行.这意味着您在开始时等待相对较长的时间,直到整个程序被翻译(即使您只调用其中的一个函数),但 OTOH 循环更快,因为不需要再次读取源代码.

In another corner of the rectangle, there are traditionally compiled languages, where usually, item #4 consists of permanently saving actual machine code to a file, which can then be run at a later time. This means you wait a comparatively long while at the beginning until the entire program is translated (even if you're only calling a single function in it), but OTOH loops are faster because the source doesn't need to be read again.

然后还有介于两者之间的东西,例如虚拟机:为了可移植性,许多编程语言不会编译为实际的机器代码,而是编译为字节码.然后有一个生成字节码的编译器,以及一个获取该字节码并实际运行它的解释器(有效地将其转换为机器代码").虽然这通常比编译和直接转为机器码慢,但将这种语言移植到另一个平台更容易,因为您只需移植字节码解释器,它通常是用高级语言编写的,这意味着您可以使用现有的编译器来执行这种有效的机器代码转换",并且不必为要在其上运行的每个平台制作和维护后端.此外,如果您可以对字节码执行一次编译,然后只分发编译后的字节码,那么这 会更快,这样其他人就不必花费 CPU 周期,例如在您的代码上运行优化器,只需支付字节码到本机的翻译费用,这在您的用例中可能可以忽略不计.此外,您没有分发源代码.

And then there are things in between, e.g. a virtual machine: For portability, many programming languages don't compile to actual machine code, but to a byte code. There is then a compiler that generates the byte code, and an interpreter that takes this bytecode and actually runs it (effectively "turning it into machine code"). While this is generally slower than compiling and going directly to machine code, it is easier to port such a language to another platform, as you only have to port the bytecode interpreter, which is often written in a high-level language, meaning you can use an existing compiler to do this "effective translation to machine code", and don't have to make and maintain a backend for each platform you want to run on. Also, this can be faster if you can perform the compilation to bytecode once, and then only distribute the compiled bytecode, so that other people do not have to spend CPU cycles on e.g. running the optimizer over your code, and only pay for the bytecode-to-native translation, which may be negligible in your use case. Also, you're not handing out your source code.

介于两者之间的另一件事是即时编译器 (JIT),它实际上是一种解释器,它以编译形式保存运行过一次的代码.这种保持"使其比纯解释器慢(例如,增加的开销和 RAM 使用导致交换和磁盘访问),但在重复执行一段代码时使其更快.对于代码,它也可以比纯编译器更快,例如只有一个函数被重复调用,因为如果不使用它,它不会浪费时间编译程序的其余部分.

Another thing in between would be a Just-in-Time compiler (JIT), which is effectively a interpreter that keeps around code it has run once, in compiled form. This 'keeping around' makes it slower than a pure interpreter (e.g. added overhead and RAM use leading to swapping and disk access), but makes it faster when repeatedly executing a stretch of code. It can also be faster than a pure compiler for code where e.g. only a single function is repeatedly called, because it doesn't waste time compiling the rest of the program if it isn't used.

最后,您可以在此矩形上找到其他点,例如通过不永久保存已编译的代码,而是再次从缓存中清除已编译的代码.这样你可以例如在嵌入式系统上节省磁盘空间或 RAM,代价是可能不得不再次编译一段很少使用的代码.许多 JIT 编译器都这样做.

And finally, you can find other spots on this rectangle e.g. by not saving compiled code permanently, but purging compiled code from the cache again. This way you can e.g. save disk space or RAM on embedded systems, at the cost of maybe having to compile a seldom-used piece of code a second time. Many JIT compilers do this.

这篇关于编译和解释有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆