21

我有一个 Rails 3.2.2 应用程序,我希望使用 JRuby 1.6.7(1.9.2 模式)运行它。

我有一个在 MRI ruby​​ 1.9.3 中运行的示例应用程序,典型的请求在 ~40 毫秒内返回:在 36 毫秒内完成 200 OK(查看:27.5 毫秒 | ActiveRecord:8.2 毫秒)

在 JRuby 下,使用相同的请求会慢 3 到 20 倍,具体取决于页面。对于与上述相同的操作,大约需要 180 毫秒:在 180 毫秒内完成 200 次 OK(查看次数:153.0 毫秒 | ActiveRecord:24.0 毫秒)

这是正常的性能差异吗?我读过 JRuby 在速度上与 MRI 大致相等。结果保存在我的 Mac 和 Windows 服务器上(不幸的是它需要运行)。用在 Tomcat 下运行的 Warbler 打包它同样慢。

以上时间来自为测试 JRuby 创建的基本 Rails 应用程序。在更复杂的应用程序上,时代相距更远。在该应用程序上,某些页面上运行了更多 ruby​​ 代码。似乎页面越依赖红宝石,我观察到的性能差异就越大。我没有调整 JRuby,因为我不知道从哪里开始。

所以我的问题是:这正常吗?我可以做些什么来调整 JRuby?

4

3 回答 3

19
Is this a normal performance difference?
I have read that JRuby is roughly equal on speed with MRI.

不,这不正常。一旦 JVM 预热,JRuby 下的 Rails 请求通常比 MRI 下的请求性能要好得多,无论是在原始执行速度还是垃圾收集方面。

听起来您的应用配置错误。首先要检查的是 Rails 本身的配置 - 请确保 Rails 不在开发模式下,并且config.threadsafe!在您的生产环境中启用。当您的应用程序运行时,线程安全模式将导致只有一个共享的 Rails 副本加载到内存中。

还要检查您的数据库配置是否利用了连接池,例如pool: 20database.yml.

最后,检查您的 JVM 和 JRuby 设置——两者都是高度可调的。您需要确保在启动时有足够的内存分配给JVM,然后有足够的内存让您的应用程序正常流畅运行;否则 JVM 将不断被迫过早且频繁地进行垃圾收集,这将显着降低性能。

例如,一些配置适中的 VPS 的设置可能类似于:

-Xmx500m -Xss1024k -Djruby.memory.max=500m -Djruby.stack.max=1024k

...但不要盲目复制这些设置!您将不得不试验并找出对您的服务器上可用的内存资源有什么好处。

也就是说,虽然 JRuby 可能会比 MRI 下多个 Rails 进程的总和消耗更少的内存,但您肯定需要预先为单个 JVM 进程分配更多的内存。对 JRuby 大方一点,JRuby 会奖励你的好意 :-)

您可以在此处阅读有关调整 JRuby 和 JVM 的更多信息:https ://github.com/jruby/jruby/wiki/PerformanceTuning

更新

config.threadsafe!Rails 4.0及以上版本不需要设置;默认情况下它是线程安全的。

于 2012-04-23T16:09:24.783 回答
4

我看到了同样的行为,但请记住 JRuby 需要更长的时间来预热。实际上,我对 JRuby 最终会赶上来有点乐观。

通过设置一些选项,可以更快地“热身”。通过设置以下环境变量,可以教导 Ruby -> Java 字节码编译器在第一次调用时 JIT 编译每个方法:

export JRUBY_OPTS="-J-Djruby.jit.threshold=1 -J-Djruby.jit.max=16384"

对我来说,在刷新 Rails 页面几次后,它仍然比 MRI Ruby 慢 2-3 倍,但至少比以前快 3 倍。

还要记住,java 运行时是以类似的方式将 java 字节码编译为机器码的 JIT,但是在使用服务器运行时时,直到一个方法被调用 10.000x 时,这个 JIT 才会启动。这也可以配置

export JRUBY_OPTS="-J-Djruby.jit.threshold=10 -J-Djruby.jit.max=16384 -J-XX:CompileThreshold=10" -J-XX:ReservedCodeCacheSize=128M"

通过这些选项,JRuby on Rails 提供了与 MRI 大致相同或更好的性能。

请注意,这些选项仅用于不耐烦的基准测试!实际上,如此激进地运行 JIT 编译几乎总是一个坏主意。您正在将宝贵的时间和内存浪费在可能只运行几次的代码的 JIT 编译上。但是,它显示了最终的 JRuby 性能如何可能比基于初始运行的预期更好。

让我知道这是否适合您。

于 2013-01-29T13:48:04.470 回答
3

使用 JAVA 7 升级到 jruby 1.6.8 或 jruby 1.7.x!

很棒的表现。

我们遇到了同样的问题,而且现在速度非常快(只需切换版本)。

于 2012-12-13T11:23:22.217 回答