欣欣向荣的 Ruby 家族

阅读数:4405 2013 年 2 月 16 日

话题:Ruby语言 & 开发

诞生于 1993 年的Ruby即将迎来自己的 20 岁生日,估计松本行弘(Matz)先生 20 年前也没有想到 Ruby 能成为一门流行的语言,长期出现在TIOBE 编程语言排行榜前 20 之列,并且有逐步上升之势。Ruby 的爱好者遍布世界各地,在中国也有庞大的RubyChina 社区。而且,除了 Matz 的 MRI Ruby 之外,还诞生了很多与其兼容的 Ruby 实现,有的旨在提升性能,而有的则是为了充分利用其他平台提供的资源,还出现了专门针对移动设备和嵌入式设备的版本。

更好的性能

早期的 Ruby 虽然受到很多人的追捧,但是性能并不理想,很多人都质疑 Ruby 的性能,建议系统中的关键部分用 C 来写。而且 Ruby 的 GC 也存在很多问题,打不打MBARI 补丁,差异巨大。出于性能的考虑,很多人开始从动手实现性能更好的虚拟机,正是他们的努力,让 Ruby 的性能获得了质的飞跃。

首当其冲的是 Koichi Sasada 开发的YARV(Yet Another Ruby VM),该项目的唯一目的就是要打造世界上最快的 Ruby 虚拟机。从早期的一些评测来看,YARV 为 Ruby 带来了巨大的性能提升,而它也成为了后来 Ruby 1.9 的官方解释器,自然不必多说了。

其次是Rubinius,在它的首页最上方有着这么一句话:

An environment for the Ruby programming language providing performance, accessibility, and improved programmer productivity.

可见它的关注点是性能、可访问性以及开发者的生产效率。Rubinius 拥有自己的字节码虚拟机,运行时,Ruby 代码会先变为字节码,随后再通过 LLVM 将字节码编译为编译为高效的字节码。而且,它还有一套精确的、带压缩的分代垃圾收集器,进一步提升了 GC 效率。

除此之外,Rubinius 还为我们带来了另一个重要的贡献,它创建了RubySpec,为其他 Ruby 实现提供了一套可以参考的实现规范,后续很多组织也参与其中,添砖加瓦,贡献了很多测试。

第三个登场的是 Phusion 出品的REE(Ruby Enterprise Edition),REE 的焦点更多地集中在服务端的 Rails 应用上,与Phusion Passenger结合在一起,可以极大程度上降低 Rails 应用的内存开销,并且提升服务响应速度。REE 的主页上提供了一套官方的对比,Apache (worker MPM) + Ruby Enterprise Edition + Phusion Passenger 的组合在这两方面要明显优于其他组合。

REE 还集成了很多第三方的补丁,比如之前提到的 MBARI、RailsBench等等,可惜它仅兼容到 Ruby 1.8.7,有点跟不上时代的节奏。

在性能上表现出众的还有 JRuby,考虑到它是运行于 Java 平台之上的,因此会在后续小结中进行重点介绍。

更多的平台

JRuby是运行于 Java 平台之上 Ruby 实现,最近刚刚发布了 1.7.2 版本,能很好地兼容 Ruby 1.8.7 和 1.9.2(JRuby 从 1.7.0 开始默认使用 1.9 模式,之前一直默认 1.8 模式)。JRuby 让 Ruby 程序能够充分利用 Java 的庞大资源,同时还提供了更好的性能。如今的 Ruby 拥有庞大的类库,但在 Rails 刚刚让 Ruby 成为众人焦点之时,Ruby 的资源并没有这么充分,即使是现在,能够借助 Java 的力量还是非常有优势的。

在 JRuby 诞生初期,开发者的主要精力集中在对 MRI 的兼容性上,但在兼容性不再是个问题时,他们就努力提升性能,他们做到了,还越做越好。例如,借助 Java 的力量,JRuby 能真正做到多线程,而不是“Green Thread”;Java 7 中新增的 invokedynamic,能够为基于 JVM 的脚本语言带来不小的性能提升,JRuby 1.7 就开始支持该特性了。JRuby 的核心开发者Charles Oliver Nutter经常会在博客上发表一些文章,介绍 JRuby 的优化方法和经验,从最近的一篇文章表明,JRuby 1.7.2 在很多方面的性能要远好于尚未正式发布的 Ruby 2.0。

有不少 Ruby 开发者之前都是 Java 开发者(Bruce A. Tate 就写过一本很出名的《From Java to Ruby》),因此如果能够充分利用之前 Java 的各种经验,也不失为一件好事。一个有着丰富 Java 经验的开发者,知道怎么对 JVM 进行调优,那他也一定能把 JRuby 的程序调校得很好。

Android 上运行的是 Java 程序,那么应该也能运行 JRuby,于是就诞生了Ruboto——这是一个用来开发原生 Android 应用的框架及工具链。此外,将 Ruby 代码编译为 Java 字节码后交付给用户,还能在一定程度上保护源代码,这也算是个额外的收获吧。

讲完了运行在 Java 平台上的 Ruby,再来看看.NET 平台上的 Ruby——IronRuby。与 JRuby 类似,IronRuby 让 Ruby 能利用.NET Framework 上的资源,.NET 开发者也能够使用 Ruby 快速地完成很多任务。可惜 IronRuby 在 2011 年 3 月之后就再也没有更新过,因此这里就不再阐述了。

Mac OS 自带了 MRI Ruby,但其实也有构建于 Mac OS X 核心技术(例如 Objective-C 运行时)之上的 Ruby 1.9 实现,即MacRuby。它的目标是在不牺牲性能的前提下享受 Ruby 的乐趣,用它来创建完善的 Mac OS X 应用程序。从官方的入门教程来看,能够很方便地使用 MacRuby 构建带 GUI 的 Mac 应用。

除了 Mac 应用,你一定也很想知道能否用 MacRuby 来开发 iOS 端的应用,到目前为止 Objective-C 仍然是官方的首选,也有人泼过 MacRuby 的冷水,但 MacRuby 的开发者并没有放弃,他们开发了RubyMotion,让开发者能方便地使用 Ruby 来开发 iPhone 和 iPad 的原生 iOS 应用,且得到众多好评

上面提到了 Ruboto 和 RubyMotion,就不得不提另一个让开发者能够使用 Ruby 来开发移动应用的MobiRuby了。MobiRuby 使用了松本行弘开发的mruby,这是一个轻量级的 Ruby 实现,可以运行 Ruby 程序,但主要的目的是嵌入其他程序,并且运行在内存受限的小型设备上,比如松本先生介绍过的 Sakura Board。MobiRuby 旨在替代移动平台上的 Objective-C/C 和 Java,目前已经能够编写 iOS 应用,更重要的是已经有 MobiRuby 的程序被 AppStore 接受了。开发团队承诺,后续也会有针对 Android 的 MobiRuby 出现。

最后再来看看MagLev,它是构建于 VMware GemStone/S 上的 64 位 Ruby 实现,让开发者能充分发挥 GemStone/S 的优势,比如有更好的性能、分布式共享缓存、企业级 NoSQL 数据管理能力等等。更重要的是它能透明地管理远大于内存上限的 TB 级别的数据和代码,出于这个原因,也许可以将 MagLev 看成一个能够运行 Ruby、存储 Ruby 原生对象的分布式数据库。

在看了这么多 Ruby 家族的成员之后,不知您有何感想?一定觉得这是个充满活力的语言吧。如果您一直在使用官方的 Ruby 实现,那么不妨试试其他的实现,也许会有别样的感觉。