9

动态语言是否比静态语言慢,例如,运行时必须一致地检查类型?

4

9 回答 9

52

不。

动态语言并不比静态语言慢。事实上,任何语言,无论是否动态,都不可能比另一种语言慢(或更快,就此而言),仅仅因为一种语言只是一堆抽象的数学规则。你不能执行一堆抽象的数学规则,因此它们永远不会慢(er)或快(er)。

“动态语言比静态语言慢”的说法不仅错误,甚至没有意义。如果英语是一种类型化的语言,那么该语句甚至不会进行类型检查。

为了让一种语言能够运行,它必须首先被实现现在您可以衡量性能,您衡量的不是语言的性能,而是执行引擎的性能。大多数语言都有许多不同的执行引擎,具有非常不同的性能特征。例如,对于 C,最快和最慢的实现之间的差异是 100000 倍左右!

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

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

事实上,我认为一个系统的性能完全取决于花在让它快速上的钱的数量,并且完全独立于任何特定的打字规则、编程范式或语言。

以 Smalltalk、Lisp、Java 和 C++ 为例。所有这些都是或曾经是高性能代码的首选语言他们都有大量的工程和研究人员花费了几个世纪的时间来使它们快速运行。它们都具有高度调整的专有商业高性能执行引擎。给定大致相同的问题,由大致可比的开发人员实现,它们的性能大致相同。

其中两种语言是动态的,两种是静态的。Java 很有趣,因为尽管它是一种静态语言,但大多数现代高性能实现实际上都是动态实现。(事实上​​,几个现代高性能的 JVM 实际上要么是伪装的 Smalltalk VM,衍生自 Smalltalk VM,要么是由 Smalltalk VM 公司编写的。)Lisp 也很有趣,因为它虽然是一种动态语言,但也有一些(虽然不多) 静态高性能实现。

而且我们甚至还没有开始谈论执行环境的其余部分:现代主流操作系统、主流 CPU 和主流硬件架构都严重偏向于静态语言,以至于对动态语言充满敌意。鉴于现代主流执行环境对于动态语言来说几乎是最坏的情况,它们的实际性能非常惊人,人们只能想象在不那么敌对的环境中的性能会是什么样子。

于 2010-02-04T14:45:11.183 回答
17

在所有其他条件相同的情况下,通常是的。

于 2010-02-04T09:54:38.870 回答
17

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

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

通常我们的意思是

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

,但情况并非如此。

类型信息可以帮助 VM 比没有类型信息更快地发送消息,但是随着 VM 中检测单态调用站点的优化,这种差异往往会消失。请参阅这篇文章中关于动态调用的“性能考虑”段落。

编译与解释与字节码 JIT 之间的争论仍然存在。一些人认为字节码 JIT 导致比常规编译更快的执行,因为由于在运行时收集了更多信息,编译更准确。阅读有关 JIT 的维基百科条目以获得更多信息。解释性语言确实比两种形式或编译中的任何一种都慢。

我就不多说了,展开热烈的讨论,我只想指出,两者之间的差距往往会越来越小。您可能面临的性能问题可能与语言和 VM 无关,而是与您的设计有关。

编辑

如果您想要数字,我建议您查看The Computer Language Benchmarks。我发现它很有见地。

于 2010-02-04T10:41:09.353 回答
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。

于 2010-02-08T13:52:41.130 回答
3

动态语言运行时只需要偶尔检查类型。

但它仍然,通常,较慢。

然而,有些人声称这种性能差距是可以攻击的。例如http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html

于 2010-02-04T10:01:26.063 回答
3

最重要的因素是考虑方法分派算法。对于静态语言,通常为每个方法分配一个索引。我们在源代码中看到的名称实际上并没有在运行时使用,而是出于可读性目的而在源代码中使用。自然地,像 java 这样的语言会保留它们并使它们在反射中可用,但就当调用方法而言,它们不会被使用。我将把反思和约束力排除在讨论之外。这意味着当调用方法时,runtmne 只需使用偏移量来查找表并调用。另一方面,动态语言使用函数的名称来查找地图,然后调用所述函数。哈希图总是比使用索引查找数组要慢。

于 2010-02-08T12:54:54.200 回答
2

不,动态语言不一定比静态语言慢。

pypy和psyco项目在为 python 构建具有数据驱动编译的 JIT 编译器方面取得了很大进展;换句话说,它们将自动编译专门针对特定常见参数值的频繁调用函数的版本。不仅仅是类型,如 C++ 模板,而是实际的参数值;假设一个参数通常为零或无,那么该值将有一个专门编译的函数版本。

这可能导致编译的代码比您从 C++ 编译器中获得的速度更快,并且由于它是在运行时执行此操作的,因此它可以发现专门针对该程序特定实例的实际输入数据的优化。

于 2010-02-04T11:07:00.897 回答
0

可以合理地假设,因为需要在运行时计算更多的东西。

于 2010-02-04T10:00:36.093 回答
0

实际上,这很难说,因为使用的许多基准并不具有代表性。随着更复杂的执行环境,如 HotSpot JVM,差异变得越来越不相关。看看下面的文章:

Java理论与实践:动态编译与性能测量

于 2010-02-08T13:16:08.690 回答