我想请有经验的同学来谈一谈 Grails 和 JRuby 的优缺点
我的理解是:
Grails 基于 Groovy 这个 JVM 语言,性能和与 Java 的兼容是优点,缺点我觉得是资源不是很多(不熟悉 Grails),而且开发上还是有学习成本(对熟悉 Rails 的人来说)
JRuby 的优点也有性能和与 Java 环境兼容,以及开发上和 Rails 没啥区别,缺点是虽然和 Rails 一样,但是会遇到很多坑,解决这些坑也存在不确定性
所以,我觉得这两个优劣性不明显,大家来谈谈呢
我个人觉得明显是 JRuby 啊...现在已经成熟多了... 一年前用了一下有点小坑,不过也没多大问题... 特别是在 jRuby 里调 Java 的时候有些情况略微有点不方便...
Grails 是基于 Groovy 语言的 仿 Rails 框架,jRuby 和 Groovy 比才对~~
Groovy 是 Java 原生,从编程习惯和认知上讲 Groovy 更具亲和力,毕竟是 Java 的亲儿子。
很久以前有很多 Gem 就是把性能有问题的部分换成 C,后来都倾向于纯 Ruby 了,因为没变快多少或者变得更慢了。二奶语言基本是 benchmark 好看但不实用...
@yggg rubyist 首选肯定是 jruby,迁移的成本比较小 @poshboytl jruby 已经做了很多类型转换的工作,现在调 java 已经很方便了 @luikore 现实情况是 C 扩展 快于 Java 扩展 远快于 纯 Ruby,当然前提是代码写得没有问题
#7 楼 @flyerhzm 说 XX 快太笼统了,浮点运算在 C 是快很多很多,因为 Ruby 每个浮点数都是一个堆上的对象,但是字符串操作却快不了多少,系统调用 (例如 fork(), accept() 之类的) 速度就很接近,用 C, Java, Ruby 写的 hello world echo server benchmark 就很相近,因为大部分时间都在系统调用上。实际 web 开发是字符串演算和系统调用占大头的,Ruby 已经优化得不错了。
另外 foreign function 调用不能忽视的一点是接口开销和内存管理导致的性能问题
在日常使用经验中,我经常用 Ruby 完成一些脚本任务,Ruby 为脚本语言优化得非常好,启动速度完爆各种 JVM 语言。我连 zsh 的 prompt 里都调用了 Ruby,如果换成 JRuby 就明显很卡。我写过一个纯 Ruby 的 parser generator,和 Haskell 的 Parsec 差不多但比 Parsec 快,我试过把瓶颈部分改写成 C,耗费了很多功夫,结果只快了 30% 左右。我比较过 Go template 和 slim 的渲染速度,结果是 slim 比 go template 快。(不过也有例外:例如 n 体问题的 benchmark 怎么写都是 Java 快,快 500 倍以上...)
@luikore 对语言的研究相当深啊 我说的速度主要是基于实际的产品,而不是单机的性能测试,当然是基于 rails 的一个项目,大概是 300k 左右的 rpm。一些 web 系统常用的扩展,比如 json/xml 解析,比如 memcache 连接,比如 http 连接等等,c 写的扩展在速度上的确要优于 java 的,java 的又优于纯 ruby 的。 jvm 启动速度慢是公认的,但是在服务器上 warm up 一会(我们的系统在 5 分钟以内),速度比 cruby 有明显的提升。所以我是开发用 cruby,生产环境用 jruby,各取所长。
#8 楼 @luikore 浮点的事情也不一定了,jruby 会得益于 jvm 的升级,莫枢去年说过,未来的数字计算可能会做优化,在函数内做类似去对象化
的事情,所以也是裸计算
#9 楼 @flyerhzm 你们用 jruby 这么久,使用 nailgun 是必须的啊,启动慢应该不是个太大的问题
话说有点跑题了,楼主说的是 jruby vs. groovy 和 rails vs grails
列一下各自的优势:
和 java 结合比较好,使用的所有对象类都是 java 类,而 jruby 不是,比如:
jruby-1.7.0.preview2 :001 > Java::JavaLang::String == String
=> false
jruby-1.7.0.preview2 :002 > Java::JavaLang::Integer == Fixnum
=> false
jruby-1.7.0.preview2 :003 > 1.is_a? Java::JavaLang::Integer
=> false
jruby-1.7.0.preview2 :004 > Java::JavaLang::Integer.new(1).is_a? Fixnum
=> false
这会在集成第三方 java 库的时候引入一部分转换工作
由于植根于 ruby 社区,在 web 开发领域有大量最佳实践和三方库可以使用,和 grails 社区的支持不是一个量级,甚至即使加上 java 社区,在 web 这块,和 ruby 社区也没有可比性
这种问题的的标准建议都是——看情况:如果你的遗留系统是大头,那么用 groovy/grails,这样要花一点时间把 rails 社区的工作再做一遍;如果未来的 web 应用是大头,那么用 jruby,这样要花一点时间分析和整合 java 遗留系统