编译和解释有什么区别?

 小兔纸77 发布于 2023-01-08 15:07

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

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

where(纠正我,如果我错了)" 解释字节码 "是Java的工作方式," 编译整个程序 "将适用于C或C++等语言.现在我们想知道,辩论并提出关于差异,相似性的错误断言和推定.为了结束这一点,我建议询问SO专家.

那么,谁能够

    命名,解释和/或引用所有主要方法(例如预编译与运行时解释)

    可视化或提供关于来源,汇编和解释之间关系的方案

    为#1的主要方法提供示例(名称编程语言).


笔记:

我不是在寻找关于不同范式的长篇文章,而是一个视觉上支持的快速概述.

我知道Stackoverflow并不打算成为程序员的百科全书(而是针对更具体问题的Q&A平台).但是既然我可以找到很多流行的问题,那种提供某些主题的百科全书式的观点(例如[1],[2],[3],[4],[5]),我就开始提出这个问题.

如果这个问题更适合任何其他StackExchange网站(例如,cstheory),请告诉我或标记这个问题以便审核.

uliwitness.. 14

几乎不可能回答你的问题只有一个简单的原因:没有一些方法,它们是一个连续统一体.这个连续体中涉及的实际代码也是完全相同的,唯一的区别在于事情发生时,以及中间步骤是否以某种方式保存.这个连续体中的各个点(不是单行,一个渐进,而是更多的是一个具有不同角落的矩形,您可以将其关闭):

    阅读代码

    理解代码

    执行你理解的东西

    沿路缓存各种中间数据,甚至将它们永久保存到磁盘.

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

解释器余额图(没有多少缓存)

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

编译器的平衡图(主要是缓存)

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

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

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

1 个回答
  • 几乎不可能回答你的问题只有一个简单的原因:没有一些方法,它们是一个连续统一体.这个连续体中涉及的实际代码也是完全相同的,唯一的区别在于事情发生时,以及中间步骤是否以某种方式保存.这个连续体中的各个点(不是单行,一个渐进,而是更多的是一个具有不同角落的矩形,您可以将其关闭):

      阅读代码

      理解代码

      执行你理解的东西

      沿路缓存各种中间数据,甚至将它们永久保存到磁盘.

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

    解释器余额图(没有多少缓存)

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

    编译器的平衡图(主要是缓存)

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

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

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

    2023-01-08 15:09 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有