JRuby
Javaでコマンドラインからインタープリタ使えないのかなーと思って、google先生に'java インタープリタ irb'って聞いてみたら、JRubyなるものが出てきた。Javaで書いたRuby。ひょっとして使えるのでは? と思って早速試す。rubyコマンドの代わりにjrubyコマンドを使えば、ほぼそのままrubyとして使える。jirbもある。それだけでは何も嬉しくないわけで、売りは何かというと、Javaのオブジェクトへのアクセスである。例えばスクリプトからSwing::JFrame.newできたりするのだ。当初の目的は、java.lang.Stringにはsplitメソッドってあるのかなー、みたいなところにあるので、辛うじて達成できそうなのだが、ふつうにString.new()してしまうとJRubyのStringクラスになってしまうので、
irb(main):049:0> require 'java' => true irb(main):050:0> String s = String.new('abcde') => "abcde" irb(main):051:0> s => "abcde"
JavaのStringクラスを試すには、java.lang.String.new()しなければダメっぽい。
irb(main):052:0> String s = java.lang.String.new('abcde') => "abcde" irb(main):053:0> s => #<#<Class:01x18e9640>:0x14b6e28 @java_object=abcde> irb(main):054:0> s.toUpperCase => "ABCDE"
つまり、Rubyで同じ名前のオブジェクトが存在するものは、クラスライブラリのフルパスを知ってなければならないわけで、結局この用途での実用は厳しいか...
ひょっとして速いのかなーと思い、一応簡単に確認。
ふつーのRubyスクリプト
hao% cat test.rb s = 'abcdefg12345abcdefg12345' for i in 1..10000 s.match('^abcde') s.match('^.*12345.*$') s.match('^.*abcde.*$') end hao% time ruby test.rb ruby test.rb 0.21s user 0.01s system 97% cpu 0.224 total
JRubyをふつーに使った場合(JRubyのStringオブジェクト)
hao% cat test2.jrb s = 'abcdefg12345abcdefg12345' for i in 1..10000 s.match('^abcde') s.match('^.*12345.*$') s.match('^.*abcde.*$') end hao% time jruby test2.rb jruby test.rb 6.90s user 0.13s system 99% cpu 7.037 total
期待はしていなかったが、激しく遅い。
さらに、Javaオブジェクトを使うようにしたらもしかして、と淡い期待を抱いたのだが...
JRubyスクリプトでJavaのStringを使った場合
hao% cat test.jrb require 'java' s = java.lang.String.new('abcdefg12345abcdefg12345') for i in 1..10000 s.matches('^abcde') s.matches('^.*12345.*$') s.matches('^.*abcde.*$') end hao% time jruby test.jrb jruby test.jrb 10.85s user 0.14s system 99% cpu 11.068 total
全然だめだ。もともとRubyのStringオブジェクトだって本体はネイティブコードになってるわけで、そこは決して速くはならない。その上、メッセージパッシングはめっちゃ重い、ってことなんだろう。考えてみれば当たり前だが。