JRuby 性能

21

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

我在MRI ruby 1.9.3中运行了一个示例应用程序,典型请求返回时间为约40毫秒: Completed 200 OK in 36ms (Views: 27.5ms | ActiveRecord: 8.2ms)

在JRuby下,相同请求的处理速度会变慢3到20倍不等,具体取决于页面。对于上述操作,需要大约180ms: Completed 200 OK in 180ms (Views: 153.0ms | ActiveRecord: 24.0ms)

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

上述时间来自为测试JRuby创建的基本Rails应用程序。在更复杂的应用上,时间差距更大。在该应用程序中,某些页面上运行的Ruby代码较多。似乎页面对Ruby依赖性越高,我观察到的性能差异就越大。因为我不知道从哪里开始,所以我没有对JRuby进行任何调优。

因此,我的问题是:这个性能差异正常吗?我应该如何调优JRuby?

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副本到内存中。
还要检查数据库配置是否利用了连接池,例如在database.yml中设置pool:20
最后,请检查您的JVM和JRuby设置 - 它们都可以高度调整。您需要确保在启动时分配了足够的内存给JVM,以及为应用程序的正常平稳运行分配足够的内存;否则JVM将不断被迫过早和频繁地进行垃圾回收,这会显著降低性能。
例如,对于一个适度规格的VPS,一些设置可能如下所示: -Xmx500m -Xss1024k -Djruby.memory.max=500m -Djruby.stack.max=1024k

...但不要盲目复制这些设置!您需要尝试并确定对于服务器可用的内存资源来说什么是最好的。

话虽如此,虽然在MRI下JRuby可能会消耗比多个Rails进程总和更少的内存,但您肯定需要为单个JVM进程分配更多的内存。慷慨地给予JRuby,JRuby将以您的善良回报您 :-)

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

更新

Rails 4.0及以上版本中,您无需设置config.threadsafe!;它默认是线程安全的。


生产模式下运行,与开发模式相比,响应速度有时会快5-6倍。至少在我的情况下是这样的。谢谢您注意到这一点。 - Aleks

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 编译成机器码,但是当使用服务器运行时,此 JIT 不会在调用方法 10.000 次之前启动。这也可以进行配置。

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的性能可能比您根据初始运行所期望的要好。

请让我知道这是否适合您。


3

升级到带有JAVA 7的jruby 1.6.8或jruby 1.7.x版本!

性能非常棒。

我们曾经遇到相同的问题,但现在只需切换版本就能大大提高速度。


2
我也遇到了同样的性能问题。尝试过Java 7和JRuby 1.7,一个新的Rails应用程序比使用MRI的强大当前项目更慢。唉。 - m4tm4t

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接