欣欣向荣的 Ruby 家族

jopen 12年前

诞生于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实现,那么不妨试试其他的实现,也许会有别样的感觉。

来自:InfoQ