我们采访了 Brian Ford(IRC 上的 ID 为 brixen),希望了解 Rubinius 项目的一些最新进展。
Brian 列出了过去几个月中 Rubinius 的更新细节:
[…] 在过去两个月中,我们提交了数百次,更改了数千行的代码。有这样一些亮点:
* Evan 加入了 JIT 架构,以及一个动态的字节码解释器。
* 一些贡献者修正了一些 Ruby 核心库类的 Bug,并且改进了性能。
* 我们重新构建了引导流程,改进了核心库的代码质量。
* 我们已经集成了一个对开发大有裨益的性能分析器,它能够以 10 倍以上的速度产生和 MRI 相同的结果。
* Adam Gardiner 已经能够使 Ruby 调试器在新的虚拟机上工作。
* 我已经更新了我们的 FFI 实现,更加接近于 Ruby 和 MRI 的 FFI gem。
* 我用一种更好的格式重写了编译器配置。
* 我们合并了 1.8 和 1.9 的 Rubyspecs。向 MSpec 中添加了一些重要的特性,使得运行 1.8 和 1.9 的 specs 更加容易。RubySpecs 惠及了每个 Ruby 实现,Engine Yard 是这个工具的主要的财政支持者。
Brian 在 RubyConf’08 的 RubySpecs 上做过演讲。请访问 http://rubyspec.org/ 获取更多信息。
LLVM 是一个构建编译器后端的架构,在某些时候能够得到一些有趣的东西。一些有意思的项目将 Ruby 和 LLVM 结合起来。Brian 解释了将会在 Rubinius 和 LLVM 上做哪些开发:
LLVM 现在还不可用。我们现在寻找哪些本地代码可以被生成。Evan 现在正在用 C++ 编写一个 JIT 汇编器。很显然这是一个时间要求非常严格的组件。生成本地代码所获得的性能提升可以弥补运行时产生代码耗费的时间所造成的性能下降。
LLVM 是一个性能强劲的巨型库,它能够使用各种先进和经典的优化技术将 C/C++ 源代码转换成多处理器的机器码。我们仍然在不停地寻找怎么平衡这个库的强劲性能。一个可能的办法是在编译的时候产生 LLVM IR,直到运行时才产生机器码。
我们应该认识到的另外一件事情是,优化能够带来的性能提升和有优化潜力的代码数量相关。在 Ruby 这个语言中,方法调用扮演着及其重要的角色。除非我们能 够非常激进地使用内联代码,否则只有很少的地方需要优化。我们正在开发一个能够支持更多运行时类型的系统,高效地对代码进行内联。
去年大部分时间我们都花在将旧的虚拟机(“shotgun”,C 语言编写的)用 C++ 重写。Brian 说 Rails 将会很快被(重新)支持:
它和 shotgun 并不是工作在同一个级别上的。使用新的虚拟机,大量的基础核心库需要重写。尤其是现在我们的 Autoload 实现不能够运行 Rails/Merb。我们将会在 Q1 关注这些问题。我们希望能够有一些关键的宏观或者微观的 Web 架构能够支持 Rails/Merb 和 ramaze,camping,Sinatra,waves。。。我有漏掉的吗?
Ruby_parser ( InfoQ 关于 ruby_parser 的报道)是由 Ryan Davis 使用 Ruby 编写的 Ruby 解析器。Brian 介绍了现阶段在 Rubinius 中解析 Ruby 代码的计划:
我的说法可能会有一些争议,但是我相信有足够的证据能够支持我的说法。使用 RubyParser 没有好处。它使用的和 MRI 原始解析器相同的技术 (LALR(1),大多数程序员对此难以理解,并且不会接触到),我们从项目开始的时候就在 Rubinius 中使用 MRI 解析器。RubyParser 比 较慢,而且引入了一个相对 MRI 不需要并且不兼容的特征。
我们最终将会使 Ruby 代码运行速度足够快,这个时候我们才会考虑类似于 RubyParser 的东西。但是到那个时候,使用这些东西就已经没有任何好处了。解析就是 Ruby 的阿基里斯的脚跟,而且对我们来说毫无意义。我们几乎直接使用 MRI 的代码。
如果各位对解析 Ruby 代码非常有兴趣,看在老天的份上,使用一个类似 PEGs 那样(Treetop 实现)的非常有用的技术吧。我们可以得到可组合的语法,开辟出新的语法以供解析。
注意: Treetop 能够使用 Ruby 来编写 PEG 解析器。
Evan Phoenix 在 RubyConf '08 上介绍了一些 Rubinius 设计上的改进。Brian 简要地介绍了这些改变:
我们一直在研究一些很大的领域,这些研究能够改良编译器技术,改良垃圾收集器,发现更好的数据结构以及类型系统。当然,这是一个递归渐进的过程。但是我们 需要记住 Rubinius 已经是一个 2 年的工程了。Evan 在这个项目的生命周期内构建了一个优秀的系统架构,我们得到了一个非常优秀的底层架构,包括新 的 C++ 虚拟机,Ruby 编译器以及 Ruby 核心库。
Rubinius 项目已经将很多改进引入到 Ruby 中;Brian 也提到了现在所有的 Ruby 丝线都在使用的 RubySpecs。另外一个起源于 Rubinius 的库是 Ruby FFI :
首先,当 Rubinius 开始推动 FFI 的时候,我们非常赞赏 JRuby 的各位开发者将 MRI gem 从其中清除掉。这是对所有的 Ruby 应用来说,一个双赢的解决方案,但是像 JRuby 这样的项目再不能支持 MRI 和 Rubinius 能够支持的 C-API 扩展。
我们之所以选择实现 FFI,是因为我们有一个比 DL 更好的 API,它和实现结合的非常紧密。所有的实现都能够兼容提供给 Ruby 代码的 API,但是在 FFI 实现中,几乎没有什么东西可以分享。
Rubinius 的 FFI 和 Ruby 的 FFI 在回调的支持上有着不同:
现在还没有一个优先级,但是我们将会加入。Rubinius 是唯一一个能够对 C 扩展作者提供 Ruby C-API 兼容性的实现。我们不需要在每一个实现上都是用 FFI,例如,你可以使用我们的 ruby.h 重编译 ImageMagick(不仅是由于我们仍然 在 C-API 上工作的缘故,ImageMagick 现在可以很好的运行,而且我们将会在 Rubinius 直接使用 MRI Readline C 扩展。
查看 InfoQ 上的 Rubinius 标签来获取更多关于 Rubinius 信息。
评论