如何在动态语言解释器/编译器(例如JavaScript)中检查类型?


11

在动态语言(例如JavaScript或Python)中,变量的类型在运行时确定。这就是为什么它们比Java之类的键入语言要慢的原因之一。

如何进行类型检查?这个过程缓慢的根本原因是什么?


它们并不慢,因为它们是动态的,它们却较慢,因为很难使其更快。JavaScript实际上是最优化的并且非常快。
德里克·里兹

Answers:


5

这个问题令人困惑。

假设类型检查很慢,但不一定是这种情况。

这个问题似乎也混淆了类型分配类型检查的过程,这是两件事。一个是在运行时完成的过程,另一个是在编译时完成的过程。我怀疑这个问题确实是在问类型分配。

类型分配会在运行时引入开销,因为计算会花费时间,这些指令会根据运行时看到的值的类型动态地决定要采取的操作。例如,在动态语言中,如果我在两件事上加上“ +”,则可能表示数字加法或字符串连接,因此我需要花一些时间查看手头上的内容来决定要做什么。有一些评估策略可以降低动态调度的成本。(例如,跟踪JIT)

关于在JavaScript中进行类型检查的信息,请参见:http : //www.cs.brown.edu/~sk/Publications/Papers/Published/gsk-flow-typing-theory/。有关类型检查器如何工作的更一般的概述,标准编程语言教科书将介绍算法。例如,http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/


我还在hashcollision.org/comprehensive/tracing.pdf中撰写了有关跟踪JIT和动态语言的小型调查报告

Javascript解释器带有标记位,每个标记位都有用于类型分配的值。您能详细说明一下吗?例如,标记位有什么用?一点对应一种类型吗?

类型的概念并不总是与表示有关。例如,我们可能有“英里”类型与“公里”类型的概念,并且有一种语言可以在编译时静态检测到计算是否不适当地对导致类型混乱的值进行运算是合理的。 。您可能会想象它们具有相同的表示形式,并且如果编译器可以在编译时保证它们永远不会混合,那么就没有理由为什么这些值在表示形式中需要附加的标签。

1
续:但是通常,尤其是在动态语言中,您想要表示不同类型的值。有几种方法可以进行这种区分。类型标签很常见,但是还有其他技术。例如,您可以将某些类型放置在内存的阻塞区域中。请参阅“以动态类型语言表示类型信息”。 lambda-the-ultimate.org/node/3912,对表示技术进行了全面调查。

7

基本上,在无类型语言中,每个引用都指向一个既包含类型又包含值的对象。例如,var a = 3指向包含值3和类型int的实例,如果执行make a = "bla",则引用将更新为包含字符串“ bla”和类型字符串的实例,旧对象将被丢弃,等等。

这很慢,因为每次a + b必须对这些基本类型进行操作(例如)运行时都必须首先取消引用对象,检查其类型是否兼容,执行操作,创建新对象。

相反,a + b在C ++或Java中,在编译时检查类型是否有效和兼容,然后将a和b存储为立即值(而不是引用),并且添加操作是对这些值的简单处理器操作。

当然,这都是非常理论上的。实际上,可以在此过程中进行很多优化来避免大部分开销,并且动态类型化的语言可以很快获得。


1
多态内联缓存之类的技巧可以极大地提高性能。关于动态语言性能,David Ungar(Self)和Eliot Miranda(Squeak,Visual Works Smalltalk虚拟机)的著作提供的信息最多。
Frank Shearar 2011年

0

每个值都与类型一起存储,首先需要检查它的类型。转换也就是从字符串到数字的转换都需要即时检查。


是的,就是这样,它只是运行时检查,没有任何幻想。
匿名
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.