More Related Content More from Uehara Junji (20) Groovy Now And Future3. Groovy年表
2003 2004 2005
8月 3月 12月 2月
▲ ▲ ▲
本日の対象
1.0b4 1.0b8 1.0b10
JSR化 JSR EA
2006 2007 2008
1.1b1
7月 2月 4月 12月 2月 12月
▲ ▲ ▲ ▲ ▲ ▲
1.0 JSR-6 1.0 1.1b2 1.5.0 1.5.4 1.5.7
1.6-rc1
GinA本対象 Grails 0.5.6 Grails 1.0 1.1b2
4. Groovy 1.1と1.5の関係
• 1.1b1, 1.1b2, ・・・, 1.1-RC1,
ときて1.5
–Java “5”の機能取り込みと、
機能が⼤幅アップしたから
–1.1正式版は存在しない。
–本資料では、1.1および1.5の新機能を
From 1.1・1.5 のマークで表⽰
–ちなみに1.6機能は From 1.6 で。
5. Groovy 1.1=1.5の主な機能
• Java 5対応
– アノテーション利⽤
– enum(ただし、インナークラスになるenumは×)
– 可変個数引数
– static import
– Generics
– 共変の戻り値
• ⾔語仕様
– エルビス演算⼦
– for(;;)形式ループ
– 名前付き引数で関数呼び出しの括弧省略
• ジョイントコンパイラ
• Expando Meta Class (EMC)
From 1.1・1.5
• 性能向上,bugfix,改良,etc,etc,
6. Groovy 1.6の主な機能
• ⾔語仕様
– マルチ代⼊(多重代⼊)
– 分岐しててもreturn省略可
– AST変換
– Groovyでアノテーション定義
• 動的な振る舞いに関するもの
– JavaインスタンスごとのMetaClass
– EMC DSL
– 実⾏時Mixin
• ライブラリ: Swing Builderの改善
• ツール: Grape
• 性能向上
• bugfix,改良,etc,etc
From 1.6
9. その前に
• 速度にこだわるべき?
–マシンも速くなってるし
–Groovyであることで遅いなら、
ボトルネックをJavaで書き直せばよい
それはものすごく簡単
• 処理系速度は体感速度に対して⽀配的
とは限らない
–ライブラリやIOの性能が⽀配的な場合も
• でも
–Groovy同⼠なら⾯⽩かろう
16. ジョイントコンパイラ
• GroovyとJavaコードが相互依存してい
てもコンパイル可能に
class A {
B b;
}
class B extends A {}
• 内部では、Groovyクラスのスタブ(メ
ソッド本体を削除したもの)を⽣成して
からJavaコンパイラを起動する
• groovycの-jオプションで実⾏
From 1.1・1.5
17. ExpandoMetaClass (EMC)
• プロパティにクロージャを代⼊する
とメソッドの様に扱える
String.metaclass.hello = { println “hello”+delegate }
“world”.hello() // helloworldが出⼒
• 簡便な動的メソッド定義。
• prototypeと同様だが、Groovyでは
クラスベースOOPと⼆本⽴て。
EMCは後付け。
From 1.1・1.5
19. Call Siteキャッシュ,Call Site最適化
• 性能向上の主因
–「メソッドコールが遅い」←Groovyの遅
さは⼤半これで説明。
• 動的メソッド呼び出しに先⽴つメソッ
ド探索をキャッシュ
–動的⾔語で効果が⼤
–JRubyが先達
–アイデア⾃体は古くからある
• JVM上で極めて有効(後述) From 1.6
20. 動的メソッド呼び出し概念フロー
呼び出し側クラス GroovyクラスX
x = new X() Class X {
x.foo()
メソッド探索
def foo() {
Pogo呼び出し
}
Pogo …Plain Old Groovy Object
23. Call Site Cache (1回⽬)
呼び出し側クラス GroovyクラスX
x = new X() Class X {
x.foo()
メソッド探索
PogoMetaClassSiteの }
インスタンスを保存
Xのメタクラス
CallSite
‘foo’ = { }
※CallSiteはSoftReferenceで保持されるので
メモリがなくなってきたら解放される
24. Call Site Cache (2回⽬)
呼び出し側クラス GroovyクラスX
x = new X() Class X {
x.foo()
保存された }
PogoMetaClassSiteの
インスタンスをcall()
Xのメタクラス
CallSite
‘foo’ = { }
※実際には呼び出しが複数あるので配列CallSiteArrayで保持
※意味が動的に変わったらCallSiteのインスタンスを差し替える
(自分で自分を置き換える。コード的にはこれがやや面白い)
25. Call Site最適化まとめ
• (1)メソッド探索コストを2回⽬以降削減
• (2)JITによるインライン展開の道を開く
– マシン語レベルでほんとに展開されているか私
は確認してません(Open JDKで確認可)がほんと
なら⾮常に効果が⾼い(連鎖的展開を導く)
– インライン展開に関してHotSpotは極めて強⼒
• アグレッシブにやって状況変わったら
Deoptimization(最適化戻し)
• (3)特定のメタメソッドについて、⾃分専⽤
の速いCall Siteを⽣成
– DefaultGroovyMethod#additionals参照
27. Grape使い⽅
• アノテーション
import org.junit.*
@Grab(group = 'junit', module='junit', version='*')
public class GrapeTestSub {
String testMethod() {
Assert.class.name
}
}
• メソッド呼び出し
Grape.grab(group:'org.jidesoft', module:'jide-
oss', version:'[2.2.0,)')
• ʼgrapeʼコマンド From 1.6
28. JavaインスタンスごとのMetaClass
• 例:
s = “xxx”;
s.metaClass.a = { println quot;hogequot;}
s.a()
// hogeが出⼒
– Groovyならもともと可能
– 「JavaクラスごとのMetaClass」は元々あった
• 参考:クラスごとのMetaClass
String.metaClass.x={println “hoge” }
“abc”.x()
// hogeが出⼒
From 1.6
29. AST変換
• AST …抽象構⽂⽊
– コンパイル中にコンパイラ内で作られる
中間データ構造
• AST変換
– 指定したアノテーションが与える規則に従って、
コンパイル時にASTを変換することで、⾔語機能
を加⼯・追加する
– デザインパターン指向プログラミング
– コンパイラソースを修正せずに⾔語機能追加。
– 定義は結構難しそう(Visitorで)
– 利⽤は簡単
From 1.6
30. AST変換の例
アノテーション 説明
@Bindable/@Vetoable プロパティの更新伝播(java.beans.
PropertyChangeSupport使⽤)
@Singleton クラスをシングルトンに変換
@Immutable インスタンス⽣成後の変更を禁⽌
@Delegate 委譲(delegation)パターン
を透過的に実現
@Lazy プロパティの怠惰(Lazily)な初期化
@Category / @Mixin カテゴリのメソッドをコンパ
イル時にmixinする
@Newify newなしで「Integer(5)」と書けばイ
ンスタンスが⽣成。(未実装?)
packageスコープの指定。フィールド
@PackageScope
については動いているようだがクラス
については?
31. AST変換: @Singleton
@Singleton class Foo {
def hello() { println quot;helloquot; }
}
Foo.instance.hello() // シングルトン参照
a = new Foo() // newでインスタンス⽣成不可
ERROR
java.lang.RuntimeException: Can't
instantiate singleton Foo. Use
Foo.instance
32. AST変換: @Immutable
@Immutable final class Foo {
String x, y
}
a = new Foo(quot;aquot;,quot;bquot;)
a.x = “hoge” 値の変更
ERROR
groovy.lang.ReadOnlyPropertyExcep
tion: Cannot set readonly property:
x
34. AST変換: @Lazy
class LazyTest {
@Lazy List s1 ={println quot;s1 initializingquot;; [1,2,3] }();
List s2 = {println quot;s2 initializingquot;; [4,5,6] }();
}
x = new LazyTest()
// s2 initializing s1の初期化は遅延される
println x.s1 s1への参照で初期化実⾏
// s1 initializing
// [1, 2, 3]が出⼒される
println x.s2
// [4, 5, 6]が出⼒される
35. AST変換: @Category/@Mixin
interface Mixed {
}
@Category(Mixed) class CatClass {
def hello() { println quot;helloquot; }
}
@Mixin(CatClass)
class MyClass implements Mixed {
}
x = new MyClass()
x.hello()
※interface Mixedの意義が不明。なんらかの処理上のマーカー?
37. 整理:さまざまな機能注⼊の⽅法
名称 注⼊単位 注⼊タイミング 対象
メソッドを書く メソッド コンパイル時 クラス
継承 メソッド群 コンパイル時 クラス
Category/use staticメソッド群 実⾏時(use⽂実⾏時) クラス
DefaultGroovyMethods staticメソッド群 Groovy処理系のコンパイ クラス(Java)
.java(DGM) ル時
MOP(invokeMethod,me メソッド呼び出し オーバーライドはコンパ クラス
thodMissing) に対応する処理 イル時に⾏われるが、処
理内容は実⾏時に決定可
インターセプタ メソッド呼び出し 実⾏時 インスタンス
の前後の処理
Mixinメソッド呼び出し メソッド群 実⾏時 クラス
1.6
Mixinアノテーション メソッド群 コンパイル時 クラス
Delegateアノテーション メソッド群? コンパイル時 クラス
EMC DSL クロージャ群 実⾏時 クラス/イン
スタンス
ExpandoMetaClass(EM クロージャ 実⾏時 クラス/イン
1.1
C) スタンス
1.5
Expando クロージャ 実⾏時 インスタンス
38. マルチ代⼊(多重代⼊)
def (a, b) = [1,2]
def (int i, String j) = [1, 'Groovy']
def a, b
(a, b) = func()
• 要素が余ったら捨て、⾜りなかったら
nullで補填
From 1.6
39. 分岐しててもreturn省略可
def even(x) {
if (x % 2 == 0) { true } else { false }
}
assert even(2) == true
assert even(1) == false
• ちなみにwhile⽂の最終評価式は値にはなら
ないようだ
From 1.6
40. EMC DSL
• 逐次プロパティに代⼊するのではなく
⼀気に定義する。
String.metaClass.define {
foo { s-> println s + delegate }
bar { println “hello” }
}
“world”.foo(“hai”) // haiworldが出⼒
“abc”.bar() // helloが出⼒
※効用: 逐次代入だと、途中で未完成状態のクラスが生じるから?
From 1.6
42. まとめ: Groovyの⽬指すもの
• Java 7がしょぼくなった今、Groovyは
⾔語機能拡張のメルティングポット
–Java 7のクロージャ(案)は、⼿ひどく複雑
そうだったので、正直ほっとしている。
• “Java is COBOL”?そうじゃあない。
“Java is C”なんだ。
–ポイントは「住み分け」
• Groovyは、JVM上にクラスをローディ
ングするための別記法。
• 「Java+Groovy」は2つで⼀つの技術
43. 参考文献
• http://glaforge.free.fr/weblog/index.php?itemid=241
• http://www.nabble.com/DGM-and-GDoc-
to14985262.html#a14985262
• http://blog.headius.com/2008/05/power-of-jvm.html
• http://glaforge.free.fr/weblog/index.php?itemid=99
• http://glaforge.free.fr/weblog/index.php?itemid=256
• http://www.infoq.com/jp/articles/groovy-1.5-new‘
• http://shootout.alioth.debian.org/
• http://d.hatena.ne.jp/masanobuimai/20081224/1230123639
• http://docs.codehaus.org/display/GROOVY/Grape
• http://docs.codehaus.org/pages/viewrecentblogposts.action?k
ey=GROOVY
• http://shemnon.com/speling/2008/04/bindable-observable-
properties.html