BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース JRuby で JVM バイトコードを生成する

JRuby で JVM バイトコードを生成する

JRuby のパフォーマンスは CRuby のそれに近づいているとはいえ、まだ十分なスピードがでないこともある。CRuby ユーザは、C/C++ を Ruby に組み込むことのできる Ryan Davis 氏の RubyInline ライブラリ(サイト・英語)を使って、Ruby の C による拡張を容易に行うことができる。JRuby 開発者の Charles Nutter 氏は現在、組み込まれた Java コードをオンザフライでコンパイルできる JRuby 用 RubyInline builder (ブログ・英語)を実装中だ。

Ryan Davis 氏による、C で記述された階乗を計算するメソッドの例(source)を次に示す。

class MyTest
 inline do |builder|
 builder.c "
  long factorial_c(int max) {
 int i=max, result=1;
while (i >= 2) { result *= i--; }
return result;
}
"
 end
end
そして、これと同じことを行う JRuby 実装は、Charles 氏 によると次のとおり(source)

class FastMath
 inline :Java do |builder|
  builder.package "org.jruby.test"
builder.java "
  public static long factorial_java(int max) {
 int i=max, result=1;
 while (i >= 2) { result *= i--; }
return result;
}
 "
 end
end

 A drawback of the RubyInline for JRuby variant is the requirement of a Java 6 JDK (for the compiler), which might not yet be available on all systems.

Another way to get fast executing code is to generate the JVM bytecode directly. While this might sound like overkill for normal applications, code generating tools like compilers definitely benefit from a  some time ago. But even with a DSL to write bytecode, this isn't a task for the faint of heart. : the generation of a method called bar that adds the lower case version of

JRuby 版 RubyInline の難点はコンパイルに Java 6 JDK を必要とすることだ。Java 6 JDK は、どのシステム上でも利用可能というわけではない。

実行速度の速いコードを書く別の方法は、JVM バイトコードを直接生成することである。これは普通のアプリケーションを考えた場合ちょっとやりすぎな気もするが、コンパイラのようなコード生成ツールは、確かに、Charles Nutter 氏が以前ブログで言及したような(source)単純なバイトコード生成 DSL の恩恵を受ける。しかし、バイトコードを記述するための DSL があったとしても、普通の人がそれを書くのは大変だ。Charles 氏のブログによると(source)String 型引数を小文字に変換したものを、同じく引数として渡された ArrayList に追加する bar というメソッドを生成する例は次のようになる。

def test_class_builder
 cb = Compiler::ClassBuilder.build("MyClass", "MyClass.java") do
 [...]
method(:bar, ArrayList, String, ArrayList) do
  aload 1
invokevirtual(String, :toLowerCase, String)
aload 2
swap
  invokevirtual(ArrayList, :add, [Boolean::TYPE, Object])
aload 2
areturn
end
[...]

 
この分野に、これも Charles Nutter 氏によるものだが、Duby という言語(ブログ・英語)が新たに加わっている。この言語は Ruby 構文のサブセットを実装し、非常に高速なバイトコードへとコンパイルする型推論ロジック(Charles 氏のブログに詳しい情報がある(ブログ・英語))によって強化されている。先ほどと同じ階乗を計算するメソッドを Duby で書くと、次のようになる。

class Fac
 def self.fac(max)
 {max => :int, :return => :int}
  i = max
  result = 1
 while i > 1
 result *= i
 i -= 1
end
  result
 end
end
これは、プログラマが利用する新しい言語というよりも、Ruby ライクな言語における型推論の可能性を示すプロトタイプであるといえる。また、パフォーマンスが重要となる部分で JRuby プログラマが Java の利用に逆戻りするのを避ける目的や、Squeak Smalltalk における Slang (Smalltalk のサブセットで、簡単に C に翻訳できる(source))のように JRuby 自体を部分的に実装する目的にも、使うことが出来る。Rubinius は Garnet と呼ばれるよく似たアプローチをとるつもりだ(Cuby/Garnet については、以前 InfoQ が Evan Phoenix 氏と対談している(source))。

さて、あなたは JRuby でどちらのコード生成方法を利用する?

原文はこちらです:http://www.infoq.com/news/2008/03/code-generation-jruby

この記事に星をつける

おすすめ度
スタイル

BT