我正在尝试阅读关于Ruby性能的内容,并且遇到了this SO thread,其中一个答案提到“方法调用,Ruby中最常见的操作之一,特别慢。”
Another thread提到“它确实”延迟查找“方法,允许灵活性。这会减慢它的速度。它还必须记住每个上下文的名称以允许eval,所以它的框架和方法调用速度较慢。“
有人可以更详细地解释为什么Ruby方法调用特别慢,并详细说明第二个线程吗?我不完全确定后期查找是什么或为什么它很慢,我不知道每个上下文的含义是什么,或者它与帧和方法调用的关系。
我(可能不正确)的理解是,由于方法可以在运行时添加或修改,因此Ruby解释器永远不会“记住”如何运行特定方法,因此每次程序运行时都必须查找方法,这就是方法调用缓慢的意思。但更正和更多技术解释会很棒。
答案 0 :(得分:18)
编译语言通常具有快速方法分派,因为调用代码知道类'vtable的索引,该类是方法指针数组。在几个指针解引用之后,调用代码可以直接跳转到方法中。编译器创建vtable,并用vtable中方法的数字索引替换源代码中的每个方法名称。
Ruby之类的动态语言通常具有较慢的方法分派,因为调用代码具有该方法的名称,而不是指针(也不是包含指针的数组的索引)。调用代码必须向对象询问其类,然后必须向类询问它是否具有该名称的方法,如果没有,请继续查询每个祖先是否具有该名称的方法的祖先链(这就是编译器在编译语言中所做的事情,这就是为什么编译速度慢而方法调度很快的原因。动态语言必须执行数十到数百个机器指令来搜索对象的类以及该方法的所有对象的祖先类,而不是几个指针解引用仅花费一些机器指令来调用方法。每个类都有一个HashTable的名字 - >方法,但带字符串键的HashTables比带有整数索引的数组慢一个数量级。
当然,有很多方法可以在动态语言中优化方法调度。在Ruby中,这就是JRuby,Rubinius和IronRuby正在开发的东西。但这是另一个问题的主题。