【问题标题】:Why are some programming languages faster than others?为什么有些编程语言比其他语言快?
【发布时间】:2011-07-08 00:14:35
【问题描述】:

我知道 ASM 基本上是最快的,但是是什么让 HLL 比抽象的 ASM 慢?我所说的抽象的意思是,例如在 C++ 中,你有一个类,需要存储关于类中存储的内容、派生的内容、私有/公共访问器和其他内容的数据。编译此代码时,是否有实际的汇编代码可以找出有关该类的信息?就像 CPython 是基于 C 构建的,因此在运行时运行的抽象和指令比 C 还要多。我所说的是否属实?我想我已经回答了自己的问题,但我想从比我自己更有经验的人那里得到答案。

编辑:我知道 Python 是被解释的,但如果它被编译,它不会比 C 慢吗?

【问题讨论】:

    标签: performance compiler-construction assembly theory


    【解决方案1】:

    这是一个广泛的问题。

    从根本上说,编译语言会像 ASM 一样被翻译成机器指令(操作码)(ASM 也是一个抽象层)。一个好的编译器实际上可能会胜过普通 ASM 编码器的结果,因为它可以检查大量代码并应用大多数程序员无法手动完成的优化规则(为优化执行排序指令等)。

    在这方面,所有编译语言都是“平等”的。然而,有些人比其他人更平等。编译后的代码执行的好坏从根本上取决于编译器的好坏,而更少取决于特定的语言。某些功能(例如虚拟方法)会导致性能损失(上次我检查虚拟方法是使用函数指针表实现的,尽管我的知识可能在这里过时)。

    解释性语言从根本上在程序执行时检查人类可读的语言,本质上需要在程序运行期间进行编译和执行阶段的等效操作。因此,它们几乎总是比已编译的对应物要慢一些。智能实现将在执行时逐步解释部分代码(以避免解释从未命中的分支),并缓存结果,以便给定部分代码只解释一次。

    还有一个中间地带,将人类可读的语言翻译成伪代码(有时称为 P 代码或字节代码)。这样做的目的是获得代码的紧凑表示,可以快速解释,但可以跨许多操作系统移植(您仍然需要一个程序来解释每个平台上的 P 代码)。 Java 属于这一类。

    【讨论】:

    • 谢谢。是的,就像我在对 paulsm4 的评论中所说的那样,该语言可能是可用的最复杂的语言,但如果它具有出色的编译器,它仍然是最快的。现在这对我来说更有意义了,所以再次感谢!
    【解决方案2】:

    其实,你的前提不一定正确。

    很多人会说,一个好的优化编译器可以胜过手工编码的汇编。

    其他人可能会说,Java 和 .Net 等即时编译器可以利用运行时启发式算法,因此优于任何静态编译的代码。

    在编译器和解释器中,我向您保证不一定有任何相关性 在语言的高级程度和运行时效率之间。 非常高级语言 可以生成非常高效的代码。

    恕我直言...

    【讨论】:

    • 所以这真的取决于编译器或解释器如何选择创建/优化实际的机器代码。如果 Python 是一种编译语言,这将说明我的观点,因为编译器(用 C 制作)可能会像在 C 的编译器中那样采取类似的步骤来创建机器代码。
    • 很多人很容易说出这样的话。为他们的主张找到客观的支持要困难得多。
    • 杰瑞·科芬,你是不是懒得谷歌了?或者只是太讨厌而无法为讨论提供任何积极的东西?
    • @paulsm4:如果您自己费心在谷歌上搜索一下,您会发现您的指控都是错误的且无法支持的。
    【解决方案3】:

    根据经验,语言越抽象(通常对程序员来说越方便),它就会越慢。 C 编译器将生成汇编代码,这就是它如此依赖系统的原因。像 Java 这样的语言在虚拟机中运行,而虚拟机本身就是一个编译程序。但这种抽象一般会减慢速度。

    但这并不是说没有例外。正如 paulsm4 所说,高级语言最终可能比低级语言更高效,因为它们可以利用各种模式(我不知道细节)。

    【讨论】:

    • 为什么现在人们说 JAVA 不再比 C++ 慢很多了?
    【解决方案4】:

    当您谈论一种语言的速度时,首先要问的是它是编译的还是解释的。 解释型语言的运行速度通常比编译型语言慢一到两个数量级。

    但这可能无关紧要。解释型语言可能还有其他优势,而您想用它做的事情可能不需要令人眼花缭乱的速度 - 如果它有速度,您就不会注意到。

    例如,命令行 shell 语言都是解释型的(据我所知),这很好,因为它们只执行一个耗时的操作系统命令,然后执行下一个命令。永远不会注意到在命令之间切换的周期。

    即使在快速编译的语言中,程序只是将一个库调用与另一个库调用绑定在一起,中间只进行一些原始数据操作,也无法从语言的速度中获益,因为一直在在地下室度过。

    语言速度的重要性在于地下室的东西。 如果您只是编写更高级别的代码,那么编译代码的速度就无关紧要了。 很多 重要的是你的代码是否调用了比它真正需要的更多的子例程。 编译器无法帮助您。 Here's an example of how to fix that kind of problem.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 2011-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-01
      相关资源
      最近更新 更多