动态语言比静态语言慢吗?

9
动态语言比静态语言慢是因为运行时需要不断检查类型吗?
9个回答

53

不。

动态语言并不比静态语言慢。实际上,任何语言(不管是动态还是静态)都不可能比另一种语言“更慢”(或者“更快”),因为一个语言只是一堆抽象的数学规则。你不能执行一堆抽象的数学规则,因此它们永远不可能变慢或变快。

“动态语言比静态语言慢”这个说法不仅是错误的,而且毫无意义。如果英语是静态语言,那么这个说法甚至无法通过类型检查。

为了使一个语言能够运行,它首先必须被实现。现在你可以衡量性能,但你测量的不是语言的性能,而是执行引擎的性能。大多数语言都有许多不同的执行引擎,具有非常不同的性能特征。例如,对于C语言,最快和最慢的实现之间的差距约为10万倍!

此外,你也不能真正地测量执行引擎的性能:你必须首先编写一些代码在该执行引擎上运行。但现在你测量的不是执行引擎的性能,而是基准代码的性能。这与执行引擎的性能几乎没有关系,当然也没有任何关系了语言的性能。

总的来说,在高性能的好设计的执行引擎上运行良好设计的代码将产生大约相同的性能,无论语言是静态还是动态、过程化、面向对象还是函数式、命令式还是声明式、惰性还是严格、纯洁还是不纯洁。

实际上,我认为一个系统的性能完全取决于投入的资金数量,而与任何特定的类型学科、编程范式或语言无关。

以Smalltalk、Lisp、Java和C++为例,它们都是高性能代码的首选语言,或曾经是。这些语言都经历了大量的工程和研究时间来使它们变得快速。它们都有高度优化的专属商业高性能执行引擎可用。在大致相同的问题实现下,由大致类似的开发人员实施,它们的性能都差不多。
其中两种语言是动态的,两种是静态的。Java很有趣,因为虽然它是一种静态语言,但是大多数现代高性能实现实际上是动态实现。 (事实上,几个现代高性能JVM实际上是假扮成Smalltalk VM、从Smalltalk VM衍生出来的,或者是由Smalltalk VM公司编写的。)Lisp也很有趣,因为虽然它是一种动态语言,但有一些(尽管不多)静态的高性能实现。
我们甚至还没有开始谈论其余的执行环境:现代主流操作系统、主流CPU和主流硬件架构都严重偏向于静态语言,甚至对动态语言有敌意。鉴于现代主流执行环境对动态语言来说几乎是最坏的情况,它们的表现非常惊人,只能想象在一个不那么敌视的环境中性能会是什么样子。

1
回答不错,但我不同意你关于金钱的建议。金钱并非固有要求,因此它无法作为一种衡量标准。即使你选择“努力”,我也会持不同意见。 - egaga
1
不错的理论,但现实与您的观点不符:http://www.techempower.com/benchmarks/#section=data-r9。在基准测试中表现最佳的所有框架都是使用静态类型语言(C++/Java)编写的,而所有动态语言则排名垫底。我不想听到“无真正苏格兰人谬误”的说法,我只关心现实情况。 - Ali
2
@ClickUpvote:这与我从数据中得到的完全不同。首先,这并没有显示动态语言与静态语言的表现差异。它只显示了一些特定版本的特定实现在一些特定基准测试上运行在一些特定操作系统和硬件平台上的性能。例如,众所周知,操作系统和CPU的选择会对性能产生很大影响... - Jörg W Mittag
1
...语言。此外,我不明白为什么“所有动态语言都排在最后”。例如,在JSON基准测试中,最后20个中有13个是静态语言,而Lua排名前十。此外,如果性能与“静态性”有关,那么在这个测试中最“静态”的两种语言Haskell和Ur应该始终位于顶部,但它们并没有。事实上,它们不仅被一些“不太静态”的静态语言超越,还被许多动态语言超越!在数据更新基准测试中,前4名是动态语言(PHP和ECMAScript),Java仅排名第8,C++排名第30,被...超越。 - Jörg W Mittag
1
PHP、ECMAScript、Python和Dart。对于Ruby,AFAICS,他们选择了最慢的Ruby实现之一(YARV),而对于Java,他们选择了最快的之一(Oracle HotSpot)。这似乎也不是特别公平。存在一些最快的动态语言实现,例如一些商业高性能CommonLisps和Smalltalks,但它们却没有被包括在内。 - Jörg W Mittag
显示剩余9条评论

18

一般情况下,如果其他条件相同,是的。


3
但是,语言本身并不快或慢!可以看一下@Jorg的回答… - SamB
1
如果问题中包含"执行引擎"这个词,那么下面的答案可能会被标记。 - Little Jack

17

首先,你必须澄清你是否考虑:

  • 动态类型与静态类型或
  • 静态编译语言与解释语言与字节码JIT。

通常我们的意思是:

  • 动态语言=动态类型+运行时解释
  • 静态语言=静态类型+静态编译

但这不一定是情况。

类型信息可以帮助虚拟机比没有类型信息更快地分派消息,但随着虚拟机中检测到单态调用站点的优化,差异往往会消失。请参见此有关VM中动态调用的文章中的“性能考虑”段落。

编译 vs. 解释 vs. 字节码JIT之间的争论仍然存在。一些人认为,字节码JIT导致比普通编译更快的执行,因为由于收集的更多信息在运行时,编译更准确。阅读JIT的维基百科条目以获取更多见解。解释语言确实比两种编译形式都慢。

我不会进一步争辩或开始激烈的讨论,我只想指出,两者之间的差距往往越来越小。你可能面临的性能问题很可能与语言和VM无关,而是与你的设计有关。

编辑

如果你想要数字,我建议你查看计算机语言基准测试。我发现这很有启示性。


当然,语言只有类型的区别 -- 其余的是实现细节。 - SamB

6

在指令级别上,目前动态类型语言的实现通常比静态类型语言的实现慢。

然而,这并不一定意味着使用动态语言实现程序会更慢 - 许多文献中都有同一个程序分别用静态语言和动态语言实现的案例,其中动态实现往往更快。例如,这项研究(PDF)将同一问题交给了使用各种语言的程序员,并进行了比较。Python 和 Perl 实现的平均运行时间比 C++ 和 Java 实现的平均运行时间更快。

这有几个原因:

1)在动态语言中,代码可以更快地实现,留下更多时间进行优化。

2)高级数据结构(映射、集合等)是大多数动态语言的核心部分,因此更有可能被使用。由于它们是语言的核心部分,所以它们往往被高度优化。

3) 程序员的技能比语言速度更重要——一个缺乏经验的程序员在任何语言中都可以编写较慢的代码。在上述研究中,每种语言中最快和最慢实现之间有几个数量级的差异。

4) 在许多问题领域,执行速度受到I/O或其他外部因素的支配,与语言无关。

5) 算法选择可能使语言选择相形见绌。在书籍《More Programming Pearls》中,Jon Bentley为一个问题实现了两个算法——一个是O(N^3),在Cray1上针对Fortran进行了优化。另一个是O(N),在TRS80家用微型机上使用BASIC实现(这是在1980年代)。当N> 5000时,TRS80表现优于Cray 1。


2
这其中有几个原因:0)C++和Java程序员是在受控条件下工作的学生,而Python和Perl程序员则是从互联网上自我选择的一群人,可以随意工作。 - igouy
@igouy:我仍然认为,当你使用Python/Perl等语言时,最重要的是不要使用如此糟糕的数据结构... - SamB
@SamB:那么你认为STL或其他C++库在速度方面很差? - Ethan
高级数据结构是大多数高级语言的核心,无论是动态的还是静态的。进行位操作的是C/C++开发人员。 - itsbruce

3

3

最重要的因素是考虑方法分派算法。在静态语言中,每个方法通常被分配一个索引。我们在源代码中看到的名称实际上在运行时并没有使用,只是为了可读性而存在。当然像Java这样的语言会保留它们,并在反射中使它们可用,但就调用方法时而言,它们并不会被使用。我将在本讨论中省略反射和绑定。这意味着当调用方法时,运行时简单地使用偏移量来查找表并调用。另一方面,动态语言使用函数名称来查找映射,然后调用该函数。哈希映射始终比在数组中使用索引查找慢。


2
不,动态语言并不一定比静态语言慢。 pypypsyco 项目一直在为 Python 构建 JIT 编译器,并具有数据驱动编译。换句话说,它们将自动编译针对特定常见参数值专门调用的函数版本。这不仅仅是按类型,像 C++ 模板那样,而是实际的参数值;例如,如果一个参数通常是零或 None,则该函数将有一个专门编译的版本适用于该值。
这可以导致编译后的代码比您从 C++ 编译器中获得的代码更快,由于它是在运行时执行的,因此它可以发现针对该程序实例的实际输入数据的优化。

0

可以合理地假设,随着运行时需要计算的事物越来越多。


2
“合理地假设”并没有真正回答问题,对吧?问题的发帖人可能已经做过这个假设并试图验证它… - Joachim Sauer

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接