【问题标题】:Interpreted vs. Compiled vs. Late-Binding解释 vs. 编译 vs. 后期绑定
【发布时间】:2011-02-22 07:36:30
【问题描述】:

Python 被编译成中间字节码(pyc)然后执行。因此,有一个编译,然后是解释。但是,长期使用 Python 的用户说 Python 是一种“后期绑定”语言,不应将其称为解释型语言。

  1. Python 与其他解释型语言有何不同?

  2. 您能告诉我在 Python 上下文中“后期绑定”是什么意思吗?

Java 是另一种语言,它首先将源代码编译成字节码,然后再解释成字节码。

  1. Java 是解释/编译语言吗?

  2. 在编译/执行方面与 Python 有何不同?

  3. 据说Java 没有“后期绑定”。这是否与 Java 程序比 Python 快一点有关?

如果你也能给我链接到人们已经讨论过的地方,那就太好了;我很想阅读更多关于此的内容。谢谢。

【问题讨论】:

  • 坦率地说,这种说法听起来像是在试图避开“解释”带来的耻辱感。如今,许多“解释”或“脚本”语言都在玩这些游戏。那么为何不?它比不这样做更快,并且不会给 interpreterruntime-compiler-launcher 增加太多复杂性。
  • 呸!我所以想在那里三振出局...
  • (1) 似乎是定义问题。如果你能找到权威的定义,那么确定语言属于哪些类别应该不成问题。如果你不能,可能没有,你可以随意分类。 FWIW、x86 和我相信 x64 由 on-CPU 软件解释并在不同的基本 CPU 上执行。一些机器语言已经由硬件直接执行(比如我学习汇编程序的控制数据机器),但大多数还没有。

标签: java python late-binding compiled


【解决方案1】:

Python 与其他解释型语言有何不同?

这涉及到头发分裂。解释语言和“托管代码”语言(如 C#)和虚拟机语言(如 Java)形成了一个奇怪的连续体。有些人会说所有语言都是“解释的”——甚至是机器语言。毕竟,CPU 的电子电路“解释”机器语言。

你能做的最好的就是说“解释”意味着有一个可见的软件层解释你的应用程序字节码。 “未解释”意味着您的软件(或多或少)由底层硬件直接执行。 “托管代码”的人可以继续分叉。

您能告诉我在 Python 上下文中“后期绑定”是什么意思吗?

变量未声明为具有类型。变量尽可能晚地绑定到一个类型——通过实际对象的赋值。

Java 是解释/编译语言吗?

是的。它被编译成字节码。字节码被解释。我更喜欢称它为解释性的。

但是,人们会(出于非常模糊的原因)不同意。任何类型的“编译”步骤的存在——无论多么小——总是让人们感到困惑。字节码的转换与程序在运行时的实际行为几乎没有关系。有些人喜欢说只有完全没有任何预处理“编译”污染的语言可以被解释。这样的例子已经不多了,因为许多语言都从对人类友好的文本翻译成对解释器友好的字节码。甚至 Applesoft Basic(早在 80 年代)都在您输入代码时完成了这种翻译过程。

一些 JVM 执行 JIT。有些没有。有些是混合物。说 JVM 只做 JIT 字节码翻译是不正确的。一些JVM会这样做。有些没有。

在编译/执行方面与 Python 有何不同?

一点也不。 Java VM 可以执行 Python。 [对于容易混淆的,这个上下文中的“python”这个词不可能意味着“python 源”。它一定是python字节码。]

据说Java没有“后期绑定”。这是否与 Java 程序比 Python 快一点有关?

也许吧。 Java 程序通常更快,因为 JIT 编译器在运行时将 Java 字节码转换为机器码。

静态(“早期”)绑定对 Java 的好处与它对真正编译的语言(如 C 或 C++)的好处不同,后者几乎没有任何类型的运行时检查。 Java 仍然执行数组边界检查之类的操作,而 C 出于原始速度的考虑而将其省略。

“延迟”绑定实际上几乎没有惩罚。 Python 属性和方法使用简单的字典查找来解析。字典是一个哈希;性能相当不错。名称的哈希值可以放入一个“interned”字符串文字池中,分摊计算哈希的成本。

为了真正的乐趣,看看 PyPy 和 RPython。这是一个可以进行 JIT 编译的 Python 解释器。你最终得到了一个 2 层的解释器。您的代码由 PyPy 解释。 PyPy 由 RPython 解释。 http://alexgaynor.net/2010/may/15/pypy-future-python/

【讨论】:

  • 您的 Java cmets 不合格;没有解释器,这很令人惊讶,因为您稍后正确地指出 Java 字节码是即时编译为机器码的。
  • JVM 是一个解释器。请解释 JVM 如何不是解释器。
  • JVM 无法执行 Python。它只能 JIT 编译 Java 字节码。 Jython 项目提供了一个编译器,可以将 Python 方言翻译成 Java 字节码。
  • Java 程序也更快,因为静态分析在编译时设置的可证明约束允许 Java 从字节码中省略大量运行时检查。当然,这会带来相应的表现力成本。
  • @Marcelo:HotSpot VM 包括解释器和 JIT 编译器。在我们吹毛求疵的同时,Jython 编译为 JVM 字节码,而不是 Java 字节码。
【解决方案2】:

后期绑定是一个与解释非常不同的概念。

严格来说,解释型语言是直接从源代码执行的。它不经过字节码编译阶段。产生混淆是因为 python 程序 一个解释器,但它解释字节码,所以它是 Python 的字节码语言,您可以将其描述为“解释”。 Python 语言本身是一种编译语言。

相比之下,如今 Java 字节码既可以解释也可以编译。它由 JIT 编译器编译为本机代码,然后直接在硬件上运行。

后期绑定是类型系统的一个属性,并且在某种程度上存在于大多数语言中,无论它们是解释的还是编译的。

【讨论】:

  • 如今,Java 被大量解释。 Hotspot JVM 最初通过解释器运行所有代码,JIT 仅编译最常执行的部分。
  • 严格来说,Android 不能算作 Java 字节码解释器。它有自己解释的字节码目标。
  • 谢谢迈克尔。蚂蚁在其他地方向我指出了这一点。我已经修改了答案。
【解决方案3】:

我们所说的绑定时间解释/编译的概念之间存在联系。

绑定时间是符号表达式绑定到其具体值的时间。这与编程语言的定义更相关,例如变量的动态与静态范围。或者静态方法与虚拟方法或动态类型与静态类型。

然后是语言的实现。预先静态知道的信息越多,编写编译器就越容易。相反,语言越晚绑定,就越难。因此,有时需要依赖解释技术。

然而,两者之间的区别并不严格。我们不仅可以认为一切最终都会被解释(参见 S.Lott 的答案),而且部分代码可以动态编译、反编译或重新编译(例如 JIT),这使得区别非常模糊。

例如,Java 中的动态类加载属于“后期绑定”类别:类的集合不是一劳永逸的,类可以动态加载。当我们知道类集时可以进行一些优化,但是一旦加载了新类,就需要使其无效。使用调试基础设施更新方法的能力也是如此:如果方法已被内联,JVM 将需要取消优化所有调用站点。

我对 Python 了解不多,但 Python 从业者可能更喜欢“后期绑定”一词以避免这种混淆。

【讨论】:

  • 很好的答案,不仅解释了解释/编译和绑定模型之间的区别,更重要的是首先导致混淆的连接。
【解决方案4】:

绑定时间是名称被解析为事物的时间。 更动态的语言倾向于后期绑定。 这可以与解释/编译分开——例如, 与 C++ 相比,objective-C 方法的解析较晚且是动态的。 Java 在类加载时完成了大部分绑定:晚于 C 但 早于 Python。

my favorite quote from Stan Kelly-Bootle's Computer Contradictionary:

绑定时间n。哈希表损坏的时刻。

==> 计算的进步可以映射到“绑定的迟到”,这让我想到了我自己所谓的 CS 所谓的职业:金色的过去、灰色的现在和美好的未来。这是我对 Synge 乐观主义的看法:除了 t=0,草更绿了。在 EDSAC I 上,我的函数(5ch 纸带子程序)在输入前大约两周被打孔、拼接和绑定。这被称为过早绑定并且需要使用松紧带的灵巧性。 FORTRAN 紧随其后,推出了一种新的装订方式:湿漉漉的纸牌,拒绝洗牌。然后使用 Algol 和 C,我喜欢静态(编译时)绑定,直到 C++ 带来动态(运行时)绑定的麻木乐趣。我目前的研究旨在将绑定延迟到执行之后。正如圣马太福音中所预言的那样,我称之为末世的捆绑:“……你在地上所捆绑的,在天上也必捆绑……”(马太福音 16:19 KJV)。

【讨论】:

    【解决方案5】:

    我认为在编译 Java 时解释 Python 的常见误解出现了,因为 Java 有一个显式编译步骤 - 您必须运行 javac 才能将 .java 源文件转换为可以运行的 .class 字节码文件。

    正如您正确指出的那样,Python 类似地将源文件编译成字节码,但它是透明地进行的 - 编译和运行通常在一个步骤中完成,因此对用户来说不太明显。

    重要的区别在于早期和后期绑定以及动态和静态类型。编译/解释的区别是没有意义和不相关的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 2017-04-11
      • 1970-01-01
      • 2010-10-20
      • 2013-03-18
      • 2013-09-21
      相关资源
      最近更新 更多