22

我正在尝试阅读有关 Ruby 性能的信息,并遇到了这个 SO thread,其中一个答案提到“方法调用是 Ruby 中最常见的操作之一,速度特别慢。”

另一个线程提到“它对方法进行“延迟查找”,以提供灵活性。这会减慢它的速度。它还必须记住每个上下文的名称以允许 eval,因此它的帧和方法调用更慢。

有人可以更详细地解释为什么 Ruby 方法调用特别慢,并详细说明第二个线程吗?我不完全确定什么是延迟查找或为什么它很慢,而且我不知道每个上下文的名称是什么意思,也不知道它与帧和方法调用有何关系。

我(可能不正确)的理解是,由于可以在运行时添加或修改方法,Ruby 解释器永远无法“记住”如何运行特定方法,因此它必须在程序运行时每次都查找该方法,而这是方法调用慢的意思。但是更正和更多技术解释会很棒。

4

1 回答 1

20

编译语言通常具有快速的方法分派,因为调用代码知道类的 vtable 的索引,这是一个方法指针数组。在几次指针取消引用之后,调用代码可以直接跳转到方法中。编译器创建 vtable,并将源代码中的每个方法名称替换为 vtable 中方法的数字索​​引。

Ruby 等动态语言的方法调度通常很慢,因为调用代码有名称对于该方法,不是指针(也不是包含指针的数组的索引)。调用代码必须向对象询问其类,然后必须询问该类是否具有该名称的方法,如果没有,则沿祖先链向上询问每个祖先是否具有该名称的方法(这就是编译器在编译语言中所做的事情,这就是编译速度慢而方法分派速度快的原因)。动态语言必须执行数十到数百条机器指令来搜索对象的类和对象的所有祖先类以查找方法,而不是只花费几条机器指令来调用方法的几个指针取消引用。每个类都有一个名称 -> 方法的 HashTable,但是具有字符串键的 HashTable 比具有整数索引的数组慢一个数量级。

当然,有一些方法可以优化动态语言中的方法分派。在 Ruby 中,这就是 JRuby、Rubinius 和 IronRuby 正在研究的内容。但这是另一个问题的主题。

于 2011-06-20T02:37:27.917 回答