Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

178 lines (128 sloc) 10.292 kb
* はじめに
本ツール CastOff は Ruby1.9.3 用のコンパイラです。
CastOff は、Ruby のメソッドを C 拡張形式のメソッドへと変換します。
C 拡張に変換することで、Ruby の仮想マシンのオーバヘッドを削減し、
対象となるメソッドを高速化することができます。
本 README では、CastOff の基本機能について紹介します。
ご質問、ご要望等があれば、shiba@rvm.jp もしくは
http://github.com/soba1104/CastOff/issues まで、ご連絡ください。
* ライセンス
Ruby 処理系のライセンスに従います。
* インストール方法
$gem install cast_off
CastOff は Ruby 処理系に一切手をくわえることなく、Ruby 処理系の拡張ライブラリとして実装しています。
このため、gem コマンド経由で容易にインストールすることができます。
ただし、脱最適化などの処理が処理系の実装依存になっているため、Ruby 1.9.3 のみの対応となっています。
Ruby1.9.3 以外のバージョンの Ruby 処理系では動作しないため、ご注意ください。
* CastOff の利用における注意点
CastOff は現在アルファ版です。重要な場面では CastOff を利用しないでください。
** 利用すると非互換になる機能
現状、CastOff を用いた場合、Ruby 処理系との非互換性が生じる可能性があります。
ここでは、現時点で把握できている、Ruby 処理系との非互換が生じる機能、
特にコンパイルエラーを出すことが出来ない機能について列挙します。
ここで列挙した機能を使用するプログラムやメソッドに対しては、CastOff を利用するべきではありません。
ここに列挙した機能以外で非互換になる点を発見された方は、
お手数ですが、shiba@rvm.jp もしくは http://github.com/soba1104/CastOff/issues まで、ご報告をお願い申し上げます。
-定数の再定義
CastOff は、コンパイルしたコードの読み込み時、もしくは最初に実行したときに定数解決を行います。
性能上の理由により、CastOff は定数解決後は常に同じ値を使いまわすため、定数の再定義に対応することができません。
定数の上書きを行うようなプログラムでは、CastOff を利用しないでください。
定数の上書きのフック、もしくは RubyVM が管理する世代番号のチェックが高速にできるようになった場合、
この非互換性は解消する予定です。
-継続(Continuation)
Ruby の継続(Continuation) を用いた場合、実行コンテキストの保存に失敗することが確認できています。
継続を使用するプログラムでは、CastOff を利用しないでください。
-メソッドや Proc のパラメータ取得
コンパイル済みメソッドや Proc に対する情報を取得しようとした場合、
コンパイル前と異なる挙動を示すメソッドがいくつかあります。
例えば、Method#arity や Proc#arity などの、メソッドや Proc の引数に
関する情報を取得しようとした場合、コンパイル前とコンパイル後では異なる値になります。
** 起動時間
CastOff は Ruby で実装しているので、CastOff を用いると、CastOff の読み込みというオーバヘッドが発生します。
このため、実行時間が短いプログラムに対してCastOff を利用すると、逆に遅くなる可能性があります。
また、CastOff を用いた場合、通常の require などの処理に加えて、CastOff がコンパイルしたメソッドの数だけ、コンパイル済みコードの読み込み、
および、メソッド上書きのフックなどの処理(以降、初期化処理と呼ぶ)が走ります。
閾値の設定次第では数多くのメソッドがコンパイルされるため、初期化処理に時間がかかります。
** コンパイル時間
CastOff は Ruby で実装しており、実装コストの兼ね合いから、コンパイル時間には配慮していません。
このため、CastOff によるコンパイルは非常に時間がかかります。
起動時間に関する注意でも述べたように、CastOff を利用した場合、
閾値の設定次第では数多くのメソッドがコンパイルされます。
閾値を低く設定しすぎると、コンパイルに非常に時間がかかるという点に、ご注意ください。
* CastOff の利用方法
CastOff が提供するコマンドラインツール cast_off では、
引数に高速化したいプログラムを指定することで、容易にコンパイルを行うことができます。
詳しくは下で解説しますが、CastOff の利用は、次のようなコマンドを繰り返し実行することで行います。
-----------------------------------------------------
$cast_off コンパイル対象のスクリプト コンパイル対象に与える引数の例
-----------------------------------------------------
例えば、次のようなスクリプトの実行を高速化したい場合、
$ruby foo.rb bar
次のように実行することで、foo.rb と、使用するライブラリをコンパイルすることができます。
(この例での bar は、foo.rb に対する引数です)
$cast_off foo.rb bar
CastOff は、コンパイルを次の2つの手順で行います。
1:コンパイル対象のメソッドを決定
2:コンパイル対象のプロファイル情報を収集し、コンパイル
この2つのステップそれぞれで対象プログラムを実行します。
このため、上の例の場合、foo.rb を、コンパイルのために2度実行します。
実行の回数は、今後、1-2の手順をまとめることで、削減する予定です。
コンパイルした後は、--run オプションを用いることで、コンパイルしたコードを読み込んで動作させることができます。
上の例の場合、次のようなコマンドを実行することで、コンパイル済みコードを用いて foo.rb を実行することができます。
$cast_off --run foo.rb bar
また、CastOff の利用で注意する必要があるのは、コンパイル時とは異なる引数を用いて実行する場合の挙動です。
上の例では、コンパイル時に bar という引数を与えています。
CastOff は、bar を引数として foo.rb を実行したときのプロファイル情報を基にコンパイルを行うため、
異なる引数を与えた場合、クラス情報の不整合を起こし、例外、もしくは脱最適化を発生させる可能性があります。
例えば、foo.rb が下の例のようなプログラムだった場合、bar という引数がわたってきた場合は String オブジェクトが、
baz という引数がわたってきた場合は Symbol オブジェクトが、sample メソッドに渡されます。
-----------------------------------------------------
# 例) foo.rb
def sample(o)
puts o.inspect
end
case ARGV.shift
when 'bar'
sample('bar')
when 'baz'
sample(:baz)
end
-----------------------------------------------------
ここで、cast_off foo.rb bar として foo.rb をコンパイルすると、CastOff は、プロファイル情報から、
sample メソッドに渡されるオブジェクトは String オブジェクトのみであるという判断を下します。
そして、sample メソッドに渡されるオブジェクトが String オブジェクトであるという前提に基づいたコードを生成します。
このため、foo.rb に baz という引数を渡した場合、sample メソッドに対し、想定していなかった Symbol オブジェクトが
渡ってきてしまい、コンパイルの前提条件が崩れてしまいます。
CastOff は、コンパイルの前提条件が崩れたことを検出したときに、例外の発生、もしくは脱最適化を行います。
例外を発生させた場合は実行を継続させることができず、脱最適化を行った場合はパフォーマンスに対するペナルティが発生してしまいます。
このような場合には、
$cast_off foo.rb bar
とした次に、
$cast_off foo.rb baz
としてください。
このようにすることで、引数を bar とした場合、引数を baz とした場合の両方のプロファイル情報を用いてコンパイルを行うことができます。
プロファイル情報やコンパイル結果を削除したい場合は、--clear という引数を与えて実行してください。
***コマンドライン引数
cast_off [options] [programfile] [arguments]
***オプション一覧
--run
コンパイル済みコードを用いて、対象プログラム[programfile]を実行します。
--clear
プロファイル結果やコンパイル結果を削除します。
name オプションによって foo と名づけたコンパイル結果を削除する場合、次のコマンドを使用してください。
$cast_off --clear --name=foo
--threshold=COUNT
COUNT 回以上実行されたメソッドをコンパイルするよう、閾値を設定します。
COUNT のデフォルト値は100です。
--name=NAME
コンパイル結果に NAME という名前をつけます。
ここでつけた名前は、コンパイル済みコードが既に存在するかどうかの確認に使用します。
コンパイル済みコードが見つかり、コンパイル対象やコンパイルやプロファイル情報
に変更が無かった場合、CastOff はコンパイル済みコードを再利用します。
name オプションを使用しなかった場合、CastOff は File.basename([programfile]) の結果を名前として使用します。
--verbose
コンパイルの進捗とコンパイル結果に関する内部情報を表示します。
-h, --help
ヘルプメッセージを表示します。
--version
CastOff のバージョンを表示します。
Jump to Line
Something went wrong with that request. Please try again.