在创建新的编程语言时,您是否会失去性能?

时间:2014-09-16 22:23:16

标签: python performance compiler-construction interpreter

这对我来说是一个非常难以解决如何正确提问的问题。

例如,Python解释器是用C编写的。假设您在Python中编写了另一个解释器,它通过CPython编译。然后你打算通过你的口译员运行一个程序。该代码是否必须通过您的解释器然后CPython?或者新的翻译是否是自包含的,并且不要求CPython解释它的输出。因为如果它不是一个独立的解释器,那么就会出现性能损失,在这种情况下,似乎所有编译器都会用低级语言编写,直到时间结束

编辑: PyPy让我对这个话题感到疑惑。我的印象是它是一个用Python编写的解释器,我不明白它如何比CPython更快。我也不明白如何在不翻译成机器代码的情况下由机器执行字节码,尽管我认为这是另一个主题。

1 个答案:

答案 0 :(得分:5)

您似乎对编译器和解释器之间的区别感到困惑,因为您在没有明确区分的情况下在您的问题中引用了这两者。 (相当容易理解......看到围绕这个主题的所有评论: - ))

编译器和解释器在某种程度上(尽管不完全是)正交概念:

编译器

编译器获取源代码并生成可以更高效执行的表单,无论是本机机器代码还是CPython字节码之类的中间形式。

可能是几乎总是编译为本机机器代码的语言的规范示例。确实设计的语言相对容易且有效地转换为机器代码。在C语言已被很好地用于操作系统编程之后,RISC CPU architectures变得流行,并且它们通常旨在使更高效将C的某些功能转换为机器代码。< / p>

因此,C的“可编辑性”已经变得自我强化。很难引入一个很难编写好的C编译器的新架构(例如Itanium,它充分利用了硬件的潜力。如果你的CPU无法有效地运行C代码,它就不能有效地运行大多数操作系统(Linux,Unix和Windows的低级别主要用C语言编写)。

口译

传统上,解释器被定义为尝试直接从其源表示运行源代码的程序。 BASIC的大多数实现都是这样的,早在好日子里:BASIC会在每次迭代中通过循环重新解析每行代码。

现代语言

现代编程语言和平台模糊了 lot 的界限。 等语言通常不会编译为本机机器代码,而是编译为bytecode等各种中间形式。

可以解释CPython的字节码,但是解释的开销要低得多,因为代码是事先完全解析的(并保存在.pyc文件中,因此在修改之前不需要重新解析它) 。

Just-in-time compilation可用于在实际运行之前将字节码转换为本机机器代码,并且具有许多不同的策略,可以准确地进行本机代码编译。

某些“传统上”通过字节码解释器或JIT编译器运行的语言也适用于ahead-of-time compilation。例如,以前版本的Android中使用的Dalvik VM依赖于即时编译,而Android 4.4引入了ART,它使用了事先编译intsead。

Python的中间表示

这是一个很好的线程,包含@AlexMartelli的真正useful and thoughful answer在由各种Python实现生成的低级编译表单上。

回答原始问题(我认为......)

传统的解释器几乎肯定会比将相同的代码编译为“裸机”机器代码更慢地执行代码,其他条件相同(通常不是这样),因为解释器强制执行每次执行时解析每行代码或代码单元的额外费用。

因此,如果传统的解释器在解释器下运行,而解释器本身就是在解释器等下运行,那么会导致性能下降,就像在VM下运行VM(虚拟机)一样VM将比在“裸机”上运行慢。

编译器不是这样。我可以编写一个在解释器下运行的编译器,该解释器在由编译器编译的解释器下运行,等等......生成的编译器可以生成与任何其他编译器生成的本机代码一样好的本机机器代码。 (重要的是要意识到编译器本身的性能可以完全独立于执行代码的性能;积极的优化C编译器通常比非优化编译器花费更多的时间来编译代码,但目的是为了生成的本机代码运行得更快。)