Groovy++
ご存知だと思いますがGroovy++というのがあります。(山本さんも記事書いてます。LT発表もされています)。
この名を聞くと、Cに対するC++のような、Groovyを拡張した別の言語のように思えますが、違いまして、利用者からすると、「Groovyコードの中で@Typedアノテーションなるものが使えるようになった」というふうに認識した方が実体にあっています。@Typedアノテーションというのは何かというと、メソッド定義に@Typedをつけると、そのメソッドの中のコードでは、
- メソッド呼び出しの動的ディスパッチ(MetaClass的なもの)が抑制され
- 静的型に基づいて最適化される
- (おまけ)静的型に基づいて型チェックされる
ちうものです。この効果は、生成されるコードをJadで逆コンパイルして覗いて見てみますと、圧倒的であることが即座にわかるのでありまして、例えば、今までGroovyで
def g() { int result = 0; for (int i=0; i<1000000; i++) { result += i } }
というコードは
public Object g() { Object obj; CallSite acallsite[] = $getCallSiteArray(); Integer result = $const$0; for(Integer i = $const$0; ScriptBytecodeAdapter.compareLessThan(i, $const$1);) { obj = acallsite[1].call(result, i); Object _tmp = obj; result = (Integer)ScriptBytecodeAdapter.castToType(obj, $get$$class$java$lang$Integer()); Integer integer = i; i = ((Integer) (acallsite[2].call(i))); Integer _tmp1 = integer; } return null; }
こういうコードにコンパイルされていたものが、以下のように@Typedをつけると
@Typed f() { int result = 0; for (int i=0; i<1000000; i++) { result += i } }
よってらっしゃい見てらっしゃい、
public Object f() { int result = 0; for(int i = 0; i < 0xf4240; i++) result += i; return null; }
こうなるわけです。
おお!!16進数になってる!!←驚くところはそこじゃないダロ*1。
まあ、この一事を持ってして、Javaなみに速くなるという事が想像つきます。
もちろん、それによって失われるものもあるでしょうけれども(Groovyっぽくなくなる)、そこは使い分けという事になるでしょうかね。「速くしたいならJavaで書けばいいじゃない」と思われるかもしれませんが、別クラスにしてさらにコンパイルしなければならないJavaと組み合わせるのは、面倒だし配布形態作ったりMavenのpom.xml書いて・・とか遥かに桁違いに厄介になってくるのでよろしくない*2。
他には、クロージャのセマンティクスとかも変わっています(クロージャ内から外のローカル変数をアクセスする際にはfinal扱いになるとか。並行処理に有利らしい。将来的にもこのままか、は不明。)。
この機能は私の以前からの望みにごく近い(よっぽど洗練されてますが)もので、ぜひ将来的にはGroovy本体に取り込まれてほしいものです。
ちなみに、@TypedはAST変換でありまして、コードジェネレーションを置き換えるように機能するようですね。
参考: