全新安装器大幅提升 Windows 平台 Ruby 性能

  • Mirko Stocker
  • 杨晨

2009 年 8 月 29 日

话题:RubyWindowsDevOps语言 & 开发架构

Antonio Canginano 的最新 Ruby 基准测试表明,IronRuby 的性能优于 Ruby 1.8.6。Luis Lavena 对此不以为然,他认为 Antonio 只是“将 IronRuby 的性能和一个在官方一键式安装中使用的那个 12 岁的老旧编译器(VC6)进行对 比”。Luis 的工作即是开发一键式安装器的替代品,这个替代品的性能将会像在第二次基准测试中那么优秀。

InfoQ 采访了Luis Lavena以期了解更多信息,而我们最想知道的,是 Ruby 1.8.6 和 1.9 的新 Windows 安装器。

虽然 Ruby 社区感到非常有用,但是事实上肯定有比写一个安装器更加激动的事情吧?

是的,事实上有更多比构建和重新构建 Ruby 以及其依赖直到正常运行更加有意思的事情可以做。但是这件事情对我来说如芒在背,不做不行。

个人来说,在开发时,我在 Windows 下将 Ruby 作为连接 C、C++ 甚至是汇编语言的连接工具和脚本工具。Ruby 在关注和自动化某些任务方面帮了我大忙。

我认为有必要分享我这么多年来在这个开放和包容的社区所获得的知识和经验。

新的安装器和旧有的有何不同呢?

新的安装器关注于正确地安装使用 Ruby,以及更加紧密方便地和 Windows 整合在一起。

另一个重点是它减少了 Linux 和 Windows 用户之间的隔阂。大多数 Windows 用户缺乏在 Windows 下构建程序的知识,他们只能等到 gem 的作者或者其他人发布 Windows 的原生 gem。

现在有个大麻烦了:因为 Ruby 创建扩展以及它与编辑器集成的方式迫使其不得不使用这个有 12 年历史的老编译器(Visual C 6.0)。

这个安装器将是全新的,而不是由一些 Ruby 核心开发者发布的程序组成,因此我们能够更加深入地调整配置和选择捆绑的插件等。

并不仅仅是这些,我们将会替代一些依赖程序,例如使用纯净的 ruby 版 readline(叫做 rb)来替代 GNU 的 Readline。

为了加快发布周期,新版的安装器不会包含任何第三方库,而这些第三方库在加入到安全器之前通常都会耗费大量的时间来检查和维护。

用户能够得到一个包含 Ruby、RubyGems 和文档的最小安装器,而且用户可以安装所需的 gems,而不用担心大量冗余的下载。

为什么创建一个全新的安装器是如此重要呢?你为啥不能仅仅重编译一下 Ruby 然后进行处理呢?

也许听起来简单,但是我们并不是简单地打包 Ruby 然后发布。

Ruby 依赖于其他的包,例如 ZLib、OpenSSL、Readline 和其他需要外部库的包。有一些外部库很难在 Windows 下找到预编译版本。

当这些程序不存在的时候,我们就不得不自己编译。一个典型的例子就是我们使用的这个还不算太旧的 OpenSSL 版本,因为它在这个平台下没有最新的版本,并且从源代码编译是一个非常复杂的任务。

有些时候我们不仅仅只是处理 Ruby,而且还要升级和调整整个 Ruby 系统的包和扩展。

如果我们已经安装了一个新 Ruby Windows 版本,那么会对那些原生扩展的 Gems 有什么影响呢?我能在新版的 RubyInstaller 上使用为旧版 Ruby 编译的 Gems 和原生扩展吗?

当你试图这样做的时候,你会发现有时候强制使一个 gem 工作在这个版本的 Ruby 上是行不通的。这就是 RubyInstaller 这些年一直在开发的原因之一。

对于那些熟悉 C 语言的开发者来说,Ruby 是全内建的,他们知道当他们编译 C 程序的时候,他们需要连接到一个叫做 CRT 的 C Runtime 库,这个库提供了一些底层服务,例如内存分配、字符串处理和 IO 等。

Windows 下到 GCC 和 VC6 编译器都是连接到同一个 CRT(MSVCRT.DLL)(更多信息请参见Luis 的博客)。

明白这个的话,问题的一部分就解决了,另外一部分是 Ruby 代码。

现在的情况是,当编译 Ruby 的时候,它在内部和一些配置文件中保存了编译器的选项,所以,当使用 VC6 构建的时候,它定义宏 RUBY_PLATFORM 为“mswin32”,当使用 GCC 的时候定义为“mingw32”。

理论上,两种都是二进制兼容的,但是现在需要明白的是,使用某些库的 Ruby 代码是如何和这些库交互的。

有些开发者在他们的库中包含了平台相关的代码,并且决定这个库是否工作在 Windows 下,他们检查 RUBY_PLATFORM,看看是否是“mswin”,“mswin32”或者是比较少见的“win”。

这些库的 RUBY_PLATFORM 的“mingw32”部分都有问题, 这些代码会让这些库认为你的运行平台是 Linux,结果当然是失败的。

所以现在是让这些开发者改正这些坏习惯的时候了。

我曾经建议使用 RUBY_PLATFORM =~ /mingw|mswin/ 这种形式来保护 Windows 代码。

你决定好了大概什么时候发布第一版吗?

这几个目标已经达到:

  1. 自动获取 Ruby 1.8.6 以及 1.9.1。
  2. 能够将这些程序绑定到安装器中。
  3. 简化使用开发工具包的用户的开发工作。
  4. 使用rake-compiler,使 gem 作者更加容易地发布 Windows 版本。

我已经在项目的TODO上写出了一些大致的任务。我将会重新安排它们,然后在RubyInstaller 的 Wiki上写出来。

一旦我们完成了文档和安装器的大部分任务,我相信我们就要准备发布第一个稳定版了。

更多关于 RubyInstaller 的信息以及 preview 1 版可以在Luis 的博客上找到。RubyInstaller 的代码库位于 GitHub。

查看英文原文:New Installer Provides a Much Faster Ruby for Windows

RubyWindowsDevOps语言 & 开发架构