【问题标题】:Are dynamic languages slower than static languages? [closed]动态语言比静态语言慢吗? [关闭]
【发布时间】:2011-01-13 00:14:56
【问题描述】:

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

【问题讨论】:

    标签: performance dynamic-languages


    【解决方案1】:

    没有。

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

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

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

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

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

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

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

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

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

    【讨论】:

    • 不错的答案,但我不同意你关于金钱的建议。金钱不是固有的要求,因此它无法作为衡量标准。如果你选择“努力”,我什至会不同意。
    • 不错的理论,但现实与你不同:techempower.com/benchmarks/#section=data-r9。所有在基准测试中表现最好的框架都是静态类型语言(C++/Java),而所有动态语言都在垫底。我对听到没有真正的苏格兰人谬误不感兴趣,我对现实感兴趣。
    • @ClickUpvote:这不是我从这些数据中得到的根本。首先,这并没有显示动态语言与静态语言相比的性能。它展示了如何在极少数特定版本的特定语言上运行特定语言的特定实现 在极少数特定操作系统上运行特定基准测试的特定版本特定硬件平台的实现执行。例如,众所周知,操作系统和 CPU...
    • … 语言。另外,我看不到“所有动态语言都处于底层”。例如,在 JSON 基准测试中,倒数 20 种语言中,有 13 种是静态语言,而 Lua 在前 10 名。此外,如果性能与“静态性”有关,那么本次测试中的两种“最静态”语言,Haskell 和Ur 应该始终处于顶部,但事实并非如此。事实上,它们不仅优于一些“静态”的静态语言,而且还有许多动态语言!在 Data Updates 基准测试中,前 4 名是动态语言(PHP 和 ECMAScript),Java 仅排在 8 位,C++ 排在 30 位,优于...
    • ... PHP、ECMAScript、Python 和 Dart。对于 Ruby,AFAICS,他们选择了最慢的 Ruby 实现之一 (YARV),而对于 Java,他们选择了最快的实现之一 (Oracle HotSpot)。这似乎也不是特别公平。一些现有的最快的动态语言实现缺失了,例如一些商业高性能的 CommonLisps 和 Smalltalks。
    【解决方案2】:

    所有其他条件都相同,通常是的。

    【讨论】:

    • 呃,但是,语言不快也不慢!查看@Jorg 的答案...
    • 也许如果问题有“执行引擎”这个词,那么下面的答案就会被标记出来。
    【解决方案3】:

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

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

    通常我们的意思是

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

    ,但不是必须的。

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

    编译、解释和字节码 JIT 之间的争论仍然悬而未决。一些人认为字节码 JIT 导致比常规编译更快的执行,因为由于在运行时收集了更多信息,编译更准确。阅读wikipedia entry about JIT 了解更多信息。解释型语言确实比这两种形式或编译中的任何一种都慢。

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

    编辑

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

    【讨论】:

    • 当然,只有打字区别适用于语言——其余的是实现细节。
    【解决方案4】:

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

    然而,这并不一定意味着程序的实现在动态语言中会变慢 - 有很多记录在案的情况下,同一程序同时用静态和动态语言实现,而动态实现已经证明是快点。例如this study (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 年代)。 TRS80 的 N > 5000 优于 Cray 1。

    【讨论】:

    • 这有几个原因: 0) C++ 和 Java 程序员是在受控条件下工作的学生,但 Python 和 Perl 程序员是从互联网拖网中自选出来的群体,可以根据自己的意愿工作。
    • @igouy:我仍然认为主要是当你使用 Python/Perl/etc 时,你最终不会使用这种糟糕的数据结构......
    • @SamB:所以您认为 STL 或其他 C++ 库在速度方面“很差”?
    • 高级数据结构是大多数高级语言的核心,无论是动态的还是静态的。是 C/C++ 的人在玩这些。
    【解决方案5】:

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

    但它仍然,通常,较慢。

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

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

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

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

        【讨论】:

          【解决方案8】:

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

          【讨论】:

          • “合理假设”并没有真正回答任何问题,是吗?该问题的发布者可能已经假设它并试图验证该假设......
          【解决方案9】:

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

          Java theory and practice: Dynamic compilation and performance measurement

          【讨论】:

            猜你喜欢
            • 2012-09-17
            • 1970-01-01
            • 1970-01-01
            • 2019-12-22
            • 2010-11-18
            • 1970-01-01
            • 1970-01-01
            • 2016-09-26
            相关资源
            最近更新 更多