【问题标题】:Why are dynamically typed languages slow?为什么动态类型语言很慢?
【发布时间】:2010-10-20 04:08:00
【问题描述】:

与静态类型语言相比,动态类型语言难以加速的原因是什么。 换句话说,静态类型语言的内在属性是什么,使它们易于优化执行速度?

【问题讨论】:

    标签: programming-languages


    【解决方案1】:

    这是因为静态类型语言通常编译为机器代码,而动态类型语言在大多数情况下由解释器运行。

    【讨论】:

    • 似乎有点过于简单化了。并非所有静态类型语言都编译为机器代码,包括任何静态 CLR 或 JVM 语言。并非所有动态类型语言都被解释,例如许多 Lisps 可以编译成字节码,还有许多 Python 和 PHP 编译器。
    • 最优秀的 Common Lisp 实现编译成机器码。有些没有解释器,他们只是做 JIT 编译。
    【解决方案2】:

    某些类型的编译时优化只有在变量的确切类型已知时才能执行。

    动态类型语言还经常添加逻辑来确定类型并确保该类型的值正确。

    【讨论】:

      【解决方案3】:

      看看这个python例子:

      def fact(n):
          if n==0:
              return n
          return n*fact(n-1)
      

      什么是n?是数字吗?它是一个字符串吗?它是您之前定义的类吗? 编译器无法知道它将获得什么输入。您必须在运行时进行大量检查,这意味着您正在为简单的操作做更多的隐式工作。

      【讨论】:

      • 实际上一些语言,如 Ocaml、F# 和 Haskell 支持类型推断 (en.wikipedia.org/wiki/Type_inference),因此编译器可以根据变量的使用情况确定变量的数据类型,而无需类型注释。例如,“n==0”,对整数文字的相等测试表明“n”是整数。由于编译器知道 'n' 是一个整数,因此 'return n' 意味着该函数也返回一个整数。因此,我们可以确定该函数接受一个 int 并返回一个 int。
      • @Princess:啊,但它是机器大小的 int 还是 bignum?您仍然需要对此进行测试(但可以有效地完成)
      • 您仍然认为过于静态 - 动态重新编译和规范如何(阅读自我论文)。实际上,通过掌握实际的类型信息,动态编译器甚至可能比静态编译器生成更快的代码,因为它甚至可能知道值范围等。这可能是投入多少资金来制作语言的问题快...
      【解决方案4】:

      在静态类型语言中访问属性/方法时,查找通常可以简化为静态函数地址。即使在较慢的虚方法的情况下,查找也只是从 vtable 读取偏移量。

      在动态语言中,名称基于字符串。想查找foo.bar?在局部变量哈希表中找到foo,然后在foo的哈希表中找到bar。在某些动态语言中,例如 Python 和 Ruby,可能会有额外的查找/方法调用来实现动态生成的属性。

      所有这些查找非常很难快速完成。 Python 拥有世界上最优化的哈希表实现之一,而 JavaScript 已经投入了数百万美元的研究资金来加快它的速度。这些策略是有效的——将 Chrome 的 JavaScript 与 IE 5 进行比较,看看有多少——但它们比静态生成函数调用要困难得多。


      我应该提到,一种语言的“动态”程度可能会有所不同。 Python 有几种不同的方式来与变量查找进行交互,这在某些情况下很好,但会使优化变得非常困难。其他动态语言(例如 Common Lisp 和 Smalltalk)在许多用例中可以与静态语言平分秋色,因为动态查找/修改更加可控。

      【讨论】:

      • 当您觉得需要时,可以在 Common Lisp 中静态指定类型。为速度而构建的实现可以生成非常快的代码。
      • 动态类型语言有时可以使用类型推断进行静态编译。有几个编译器是compile Python to C这种方式的。
      【解决方案5】:

      动态类型语言必须在运行时进行所有检查,因为在执行过程中类型可能会发生变化。

      静态类型语言在编译期间解析所有类型,因此一次性一次性消耗成本。

      这是动态类型语言通常较慢的主要原因。但还有其他事情需要考虑。很大程度上取决于编译器或解释器、GC 实现、调度表布局和查找算法以及其他优化。

      这完全取决于实现:动态类型语言可以比编译语言更快,它只是需要更多的工作来完成。

      【讨论】:

      • 可以编译动态语言;-)
      • 您的意思是动态类型语言的非常好的实现可能比静态类型语言的非常差的实现要快。
      【解决方案6】:

      您的问题有点不对劲,因为动态类型语言实际上并不慢。许多例子可能在实践中,但其他例子很快(其中快速意味着“与 c 相当可比”或类似的东西,cf common lisp)。

      许多动态语言在 VM 上运行,甚至是解释型语言,这可能会导致可以避免的速度变慢。在某个级别上,静态语言编译器(或已做出正确承诺的动态编译器)可以使用的优化在完全动态的情况下是不可能的。

      但是,如果您只是在考虑例如 python 和 c++ 之间的差异,那么真正的问题并不是动态与静态。

      【讨论】:

      • 还需要注意的是,例如,一些较新的 Javascript 字节码翻译器的执行速度通常与 C++ 一样快。
      猜你喜欢
      • 2016-09-26
      • 2016-03-31
      • 1970-01-01
      • 2011-09-12
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多