我正在做一个针对Java人群的关于Ruby生态系统的演讲。
尽管我将强调生产率带来的时间收益,并且较慢的仍然可以足够快,但如果我能提出一个基准测试,显示Ruby在某些数字处理方面优于Java,那就太好了,一旦问题出现,为了双关语的目的。
不幸的是,经过几个小时的搜索和实验,我仍然一无所获。
谁能想出一个基准来表明事情不是完全黑白分明的?
理想情况下,它应该比较最新版本的java 1.6/1.8和最新版本的cruby。任何涉及rubinius/jruby的示例也值得赞赏。我想你是找不到东西的。说到优化,Ruby和Java实际上非常相似,两者的主要难点都是盒装对象和动态方法调度,它们都继承自Smalltalk (Ruby直接继承,Java通过其主要灵感Objective-C)。Java vm是动态调度OO语言最先进的生产执行环境。例如,Scheme可能有一些研究的东西,甚至更快,但是当涉及到生产就绪的工业强度实现时,Azul Zing, Oracle HotSpot, Oracle JRockit, IBM J9和朋友们轻而易举地获胜。
所以,除非Rubinius的家伙们发明了一些被Smalltalk/Java社区忽视的东西,否则你最多只能得到相同的性能。
最好的选择是而不是数字处理,而是文本处理。这正是Ruby的Perl遗产的亮点所在。大多数Java实现的正则表达式引擎的性能都不是很好(尽管它们正在变得更好),而Onigmo实际上相当好(尽管不如Perl的好)。另外,Ruby独立于字符编码的字符串允许您消除对字符串的重新编码,而Java的字符串总是必须编码为UTF-16或从UTF-16编码,除非输入和输出编码是UTF-16,这是极不可能的。在Ruby中,您最多只需要转码一次,即使您的输入和输出编码不同,您也可以将内部编码设置为与输入或输出编码相同,因此您只需在输入或输出期间进行转码,而不必同时进行转码。
有 Ruby与C竞争的例子,因为"每个人都知道"™C比Java快,这肯定意味着Ruby比Java快,对吧?对吧?
[实际上,找到Ruby优于C的例子可能更容易,因为动态优化,如推测内联,多态内联缓存,自适应优化,以及动态反优化启用的"不安全"优化,在典型的C实现中不存在]
特别是Rubinius的Hash
类(用Ruby编写)并不比YARV的Hash
类(用c编写)慢得多。
一个非常令人兴奋的例子是JRuby+Truffle+Graal+TruffleC可以在JVM之上的C解释器中运行YARV的C扩展(!!)比YARV本地运行C扩展要快:
- JRuby+Truffle的高性能C扩展
- 以模块化的方式动态组合语言:支持动态语言的C扩展作者:Matthias Grimmer, Chris Seaton, Thomas Wuerthinger, Hanspeter Mössenböck,第14届国际模块化会议论文集,2015.
- 多语言运行时中的高性能跨语言互操作性作者:Matthias Grimmer, Chris Seaton, Roland Schatz, Thomas Wuerthinger, Hanspeter Mössenböck,第11届动态语言研讨会论文集(DLS)
我最终将使用一个简单的正则表达式示例- /(foo|bar)*/
,试图匹配'foobar' * n
:
puts 'Done matching' if ('foobar' * 666).match(/(foo|bar)*/)
和
import java.util.Collections;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class SimpleRegexTester {
public static void main(String[] args) {
String repeatedFooBar = String.join("", Collections.nCopies(666, "foobar"));
Pattern p = Pattern.compile("(foo|bar)*");
Matcher m = p.matcher(repeatedFooBar);
if (m.matches())
System.out.println("Done matching");
}
}
它不是技术上更快,java版本甚至不工作(抛出StackOverflowError
)。我的观点是,java对于所有可能的场景都是更好的优化。
它还提供了一个很好的过渡来讨论代码的简洁性,特别是在我展示了java8版本之前。
我曾经参加过一个JRuby开发人员的演讲,他指出他们从JRuby中获得了比原生Ruby更好的基准测试,这是因为Sun/Oracle花了大量的钱让Hotspot在JIT优化方面表现得非常好。
我怀疑,一旦JIT有机会发挥它的魔力,你可能会找到一些JRuby和普通Java一样快的基准测试。
所以尝试一个服务器应用程序,也许是一个web应用程序,启动它并在开始测量性能之前至少运行一次代码。这应该意味着JIT已经发生了,并且您可能会发现性能等同于普通Java。
即便如此,拖拉机也不是赛车。一个善于赢得比赛,另一个善于犁地。同样,存在多种语言也是有原因的。