这是我在阅读解释和编译语言时所想知道的。

毫无疑问,Ruby是一种解释型语言,因为源代码是在执行时由解释器处理的。
相反,C是一种编译后的语言,因为必须编译源代码。代码首先根据机器,然后执行。这样的结果是执行起来更快。

现在使用Python:


导入时的python代码(somefile.py)创建文件(somefile.pyc)在同一目录中。假设导入是在python shell或django模块中完成的。导入后,我稍稍更改了代码,然后再次执行导入的功能,以发现它仍在运行旧代码。这表明* .pyc文件是编译后的python文件,类似于C文件编译后创建的可执行文件,尽管我无法直接执行* .pyc文件。
当直接执行python文件(somefile.py)时(./somefile.py或python somefile.py)没有创建.pyc文件,并且按指示解释行为的方式执行了代码。

这些建议在每次将python代码导入新进程时都会对其进行编译,以创建.pyc,而直接执行时会对其进行解释。

那么我应该将其视为哪种类型的语言?解释或编译的吗?
它的效率与解释和编译的语言相比如何?

根据Wiki的“解释的语言”页面,它被列为编译为虚拟机代码的语言,这意味着什么通过那个?

评论

什么时候可以怀疑Ruby是否是一种解释语言?编译时。 :) macruby.org

值得注意的是,没有严格意义上的现代语言被解释。实际上,它们全部都编译为字节码。

@温斯顿·埃韦特:太棒了! Applesoft Basic(在1980年代)是字节码编译的。在这种情况下,“现代”表示生活记忆中的每种解释语言,唯一可能的例外是一些基本的Dartmouth Basic实现。

>>相反,C是一种编译语言<< << root.cern.ch/drupal/content/cint

@ S.Lott:调用Applesoft和80年代的BASIC解释器执行的“标记化”过程是“字节码编译”,这有点不明智。是的,用户输入的程序代码以压缩形式存储在内存中,每个保留字一个字节,但是除非您键入RUN,否则什么也不会做。好像您有一个编译器执行了词法分析步骤,然后输出了每次运行程序时都必须重新解析的令牌流。根本不像javac这样的现代字节码编译,它包括词法分析,解析和优化。

#1 楼

值得注意的是,语言不会被解释或编译,而是语言实现可以解释或编译代码。您注意到Ruby是一种“解释语言”,但是您可以编译Ruby和MacRuby,因此它并不总是一种解释语言。

几乎每个Python实现都包含一个解释器(而不是编译器) )。您看到的.pyc文件是Python虚拟机的字节码(类似于Java的.class文件)。它们与C编译器为本机机器体系结构生成的机器代码不同。但是,某些Python实现确实包含一个即时编译器,该编译器会将Python字节码编译为本地机器代码。

(我说“几乎每个”,因为我不知道任何适用于Python的本机编译器,但我不想宣称任何地方都不存在。)

评论


根据您的定义,存在适用于Python的本机编译器。有些只编译python的子集。其他人实现所有python,但使用python API实际执行它在C中无法执行的操作。

–温斯顿·埃韦特(Winston Ewert)
2010-12-8 15:02

我认为您实际上是在描述Python是我所谓的“半编译”或实际上可以完全编译的。半编译的意思是由于通常将其编译为Python虚拟机使用的“中间语言” .pyc文件,因此通常以这种“半编译”形式运行,这通常会使代码比解释代码的普通运行时解释。有趣的是,半编译代码有时可能比本地编译的代码更快(例如C#通常比C ++更快)。

–克里斯·哈克罗(Chris Halcrow)
2015年6月25日4:16在

Cython将Python代码编译为C,以便可以将其编译为共享对象。

– Greyfade
15年10月23日在6:04

以这种方式区分字节码和机器码是相当随意的。编译Java:javac编译器生成包含低级指令的类文件,这些指令可以在虚拟机(例如热点)中直接执行,也可以直接由硬件(例如在具有Jazelle扩展名的ARM处理器上)执行。据我所知,没有技术上的理由不能将类似的处理器架构设计为直接执行python vm指令。

–法律
2015年10月23日在12:11



@Jules巧合的是,Jython代码实际上已编译到.class文件中,我相信这些文件将被重用,直到您修改py源。

– JimmyJames
17年8月18日在16:41

#2 楼

Python将被解释为字节码。首先将.py源代码编译为字节代码.pyc。可以解释此字节码(官方CPython),或编译JIT(PyPy)。可以将Python源代码(.py)编译为不同的字节代码,例如IronPython(.Net)或Jython(JVM)。 Python语言有多种实现。官方的一种是字节码解释的。也有字节代码JIT编译的实现。

要对各种语言的实现进行速度比较,可以在这里尝试。

评论


感谢提供的信息。根据基准测试,python的性能下降了!

–crodjer
2010年12月8日在8:18

我给的链​​接非常清楚地指出,这些是语言实现的有缺陷的基准。如果您过于担心执行性能,那么Python不应是您选择的语言。如果仍然要比较,请比较相似的语言。字节码解释的官方CPython可以与JIT编译的Ruby相媲美或更快。

–父亲
2010-12-8 14:42

@ jase21-“我在2006年的计划是将Psyco中实现的技术移植到PyPy。PyPy将使我们能够构建更灵活的JIT专业化工具,使其更容易进行实验,而又不必与开发过程保持同步Python语言。” psyco.sourceforge.net/introduction.html

–igouy
2010-12-11 18:25

@ jase21-“使python代码比C计数器部分运行得更快”-我们是否应该相信您的意思?

–igouy
2010-12-11 18:28

答案中的链接已损坏。

–巴西
16年1月2日,下午5:09

#3 楼

编译与解释在某些情况下可能会有所帮助,但是从技术意义上讲,这是错误的二分法。

编译器(广义上)是翻译器。它将程序A转换为程序B,并在将来使用机器M将其转换为程序。

解释器(广义上是执行器)。它是执行程序A的机器M。尽管我们通常从此定义中排除物理机器(或行为与物理机器类似的非物理机器)。但是从理论上讲,这种区别在某种程度上是任意的。例如,以re.compile为例。它会将正则表达式“编译”为中间形式,然后解释/评估/执行该中间形式。


最后,这取决于您在说什么级别的抽象,以及你在乎什么人们说“已编译”或“解释”是对过程中最有趣部分的广义描述,但实际上,大多数程序都是以一种或另一种方式进行编译(翻译)和解释(执行)的。

CPython(最流行的Python语言实现)对于执行代码最为有趣。因此,通常将CPython描述为解释型。虽然这是一个宽松的标签。

#4 楼

虚拟机代码是原始源代码(字节代码)的更紧凑版本。由于它不是机器代码,因此仍需要由虚拟机解释。不过,它比人类编写的原始代码解析起来更容易,更快捷。

一些虚拟机在第一次解释虚拟机代码时会生成机器代码(只是及时编译-JIT)。 。以下调用将直接使用此机器代码,从而导致更快的执行。

据我所知,Ruby> = 1.9也使用类似Python的虚拟机。

#5 楼

Python运行时在虚拟机上运行自定义目标代码(字节码)。

编译过程将源代码转换为目标代码。

为了加快处理速度,目标代码(或字节码,如果您愿意的话)存储在磁盘上,以便下次运行程序时可以重新使用。