编译语言和解释语言有什么区别?

53

编译语言和解释语言的相对优劣如何?


3
但我的问题不同,我想知道使用解释器和编译器的背后的直觉是什么。 - amine
2个回答

147

两种方法在优劣方面都没有明显的优势 - 如果一种方法总是更好,那么我们很可能会到处使用它!

总体而言,编译器具有以下优点:

  1. 因为编译器可以一次性看到所有代码,所以在生成代码时可以执行许多分析和优化,使最终版本的代码比单独解释每行代码更快地执行。

  2. 编译器通常可以生成低级别的代码来执行高级别的想法,例如内存查找表中的“动态调度”或“继承”。这意味着生成的程序需要记住关于原始代码较少的信息,从而降低了生成程序的内存使用率。

  3. 编译代码通常比解释代码更快,因为执行的指令通常只是针对程序本身,而不是程序本身加上解释器开销。

总体而言,编译器具有以下缺点:

  1. 一些语言特性(例如动态类型)很难有效地编译,因为编译器无法预测直到实际运行程序才会发生什么。这意味着编译器可能不会生成很好的代码。
  2. 编译器通常具有较长的“启动”时间,因为需要执行它们所做的所有分析的成本。这意味着在像 web 浏览器等需要快速加载代码的环境中,编译器可能会比解释器慢,因为它们优化了很少运行多次的短代码。

总体而言,解释器具有以下优点:

  1. 因为解释器可以按照编写的方式读取代码,而且不必执行生成或优化代码的昂贵操作,所以它们通常比编译器更快地启动。

  2. 因为解释器可以看到程序运行时的情况,所以解释器可以使用许多编译器可能无法看到的动态优化。

总体而言,解释器具有以下缺点:

  1. 解释器通常具有比编译器更高的内存使用率,因为解释器需要在运行时保留有关程序的更多信息。

  • 解释器通常会在解释器的代码内部花费一些CPU时间,这可能会减慢正在运行的程序。

  • 因为解释器和编译器具有互补的优缺点,所以越来越多的语言运行时将两者元素结合起来。Java的JVM就是一个很好的例子 - Java代码本身是经过编译的,最初是解释执行的。然后,JVM可以找到已经运行了很多次的代码并将其直接编译为机器码,这意味着“热门”代码可以获得编译的好处,而“冷门”代码则不能。 JVM还可以执行许多动态优化(如内联缓存),以加快性能,这是编译器通常无法做到的。
    许多现代JavaScript实现使用类似的技巧。大多数JavaScript代码都很短,且功能不强,因此它们通常首先使用解释器。但是,如果清楚地表明代码正在反复运行,许多JS引擎将编译代码 - 或至少编译其中的一些部分 - 并使用标准技术进行优化。最终结果是代码在启动时快速(有助于快速加载网页),但随着运行次数的增加越来越快。
    最后一个细节是,语言并非编译或解释。通常,C代码是经过编译的,但是有C解释器可用,可以更容易地调试或可视化正在运行的代码(它们经常用于入门编程课程 - 或者至少曾经是这样)。JavaScript曾经被认为是解释性语言,直到一些JS引擎开始将其编译。一些Python实现是纯解释器,但是您可以获得生成本机代码的Python编译器。现在,某些语言比其他语言更容易编译或解释,但是没有任何东西阻止您为任何特定的编程语言制作编译器或解释器。例如,有一个名为Futamura投影的理论结果表明,任何可以解释执行的内容都可以编译。

    38
    这个答案链接在learncpp.com上,作为“编译器与解释器优劣比较”的好比较。虽然这个问题可能会产生很多基于意见的答案,但这个答案似乎不是其中之一。如果我有3k声望,我会对原来的问题进行一些轻微的编辑,将“哪个更好”替换为“两者的区别是什么”,并投票重新打开。 - Egalth

    -5

    因为启动时间更短,而且可以直接读取解释器程序,这对我来说是一个明智的选择。


    你的回答可以通过提供额外的支持信息来改善。请编辑以添加更多细节,例如引用或文档,以便他人可以确认你的答案正确。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接