Eclipseでのインポート編成
EclipseでJAVAコードを編集するのにインポートの編成(Ctrl+Shift+O)を良く使います。
ただ、これを使うとJUnitでテストを書いている場合に
import static org.junit.Assert.*;
の様なコードを書いてあっても以下の様に使っているimportのみ展開されてしまいます。
import static org.junit.Assert.assertArrayEquals;
これだと、別のassertXXの関数を書こうと思った場合でもコード補完が効かないため不便だと感じていました。
何とかならないものかと調べてみると解決方法をまとめている方がいらっしゃいました。
http://ameblo.jp/ouobpo/entry-10103239727.html
設定方法は以下
- 設定(Preferences)→Java→コード・スタイル(Code Style)→インポート編成(Organize Imports)を開く
- ".* (例 'java.lang.Math.*') に必要な静的インポート数(&S):"の項目にある"99"という数字を"1"に変更
- "Number of &static imports needed for .* (e.g. 'java.lang.Math.*'):"
これを設定するだけで、煩わしかったimportが快適になりました。
アジャイルプラクティス
先月末に「アジャイルプラクティス」を読んでみた。
アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣
- 作者: Venkat Subramaniam,Andy Hunt,木下史彦,角谷信太郎
- 出版社/メーカー: オーム社
- 発売日: 2007/12/22
- メディア: 単行本(ソフトカバー)
- 購入: 35人 クリック: 995回
- この商品を含むブログ (293件) を見る
ここで書かれている事はアジャイルに関わらず「そうだよなぁ」と思うことが多い。
いくつもの本を読んでみても実践しなければ結局身にはならない。
アジャイルの手法自体はXPの頃からあるような良いものをなるべくリスクを減らして作ろうという姿勢が見える。
で、問題になるのは本書の冒頭でも書かれているが、全員が共通意識を持ってプロジェクトに望むこと。
これが難しい。。。
管理者だけ、リーダーだけがプロフェッショナルなのでは無く、プロジェクトに関わる全ての人間にプロフェッショナルであること、主体的に考え、動くことが求められる。
しかし、実際には取り敢えず給与だけ稼げれば良いというメンバが多い。(特にうちの会社)
動機づけをしようとしただけで、あれこれ言い訳をしてしまう。
新しいものが好きなSE/PGが自分の周りに少なく、保守的で刺激が少なすぎて物足りない。
こう「余計なことはしたくない。」オーラが・・・。
ということで、まだ染まっていない若い子に教育して少しでも自分が楽をしたい。(結局それか^^;)
Groovy++計測(2)
前回の続き
今度は単純ループで計測
@Typed def loop1() { int k = 0 for (int i=0; i<1000000; i++) { k++ } } def loop2() { int k = 0 for (i=0; i <1000000; i++) { k++ } } start = System.currentTimeMillis() loop1(); t = System.currentTimeMillis() - start println 'Loop Counter ' + t + "ms" start = System.currentTimeMillis() loop2(); t = System.currentTimeMillis() - start println "Loop Counter " + t + "ms"
結果
$ groovy loop.groovy Loop Counter 0ms Loop Counter 453ms
圧倒的。。。
コンパイル結果
public Object loop1() { int k = 0; for (int i = 0; i < 1000000; ) { k++; i++; } return null; } public Object loop2() { CallSite[] arrayOfCallSite = $getCallSiteArray(); int i = 0; int k = i; Object localObject1; if )((!BytecodeInterface8.isOrigZ())( || (__$stMC) || (BytecodeInterface8.disabledStandardMetaClass())() { int j = 0; for (ScriptBytecodeAdapter.setGroovyObjectProperty)((Integer)DefaultTypeTransformation.box(j), $get$$class$loop(), this, "i"); ScriptBytecodeAdapter.compareLessThan(arrayOfCallSite[19].callGroovyObjectGetProperty(this), (Integer)DefaultTypeTransformation.box(1000000))(; ) { int k; Object tmp100_95 = arrayOfCallSite[20].call)((Integer)DefaultTypeTransformation.box(k = k))(; k = DefaultTypeTransformation.intUnbox(tmp100_95); tmp100_95; Object tmp132_127 = arrayOfCallSite[22].call(localObject1 = arrayOfCallSite[21].callGroovyObjectGetProperty(this))(; ScriptBytecodeAdapter.setGroovyObjectProperty(tmp132_127, $get$$class$loop(), this, "i"); tmp132_127; } } else { int m = 0; for (ScriptBytecodeAdapter.setGroovyObjectProperty)((Integer)DefaultTypeTransformation.box(m), $get$$class$loop(), this, "i"); ScriptBytecodeAdapter.compareLessThan(arrayOfCallSite[23].callGroovyObjectGetProperty(this), (Integer)DefaultTypeTransformation.box(1000000))(; ) { int n; (k = (n = k) + 1); Object tmp235_230 = arrayOfCallSite[25].call(localObject2 = arrayOfCallSite[24].callGroovyObjectGetProperty(this))(; ScriptBytecodeAdapter.setGroovyObjectProperty(tmp235_230, $get$$class$loop(), this, "i"); tmp235_230; } } Object localObject2; return null; return null; }
実行速度の面ではかなり使えるということが計測結果からもコンパイルされたコードからもわかった。
但し問題が無いわけでは無い。
例えばループ処理でfor(int i ...の様に型宣言を入れているがGroovyであれば本来このような型定義は必要ない。実行時に動的に解決をしてくれる。
しかし、@Typedを付けた場合には静的な型を必要とするため型宣言を入れないとコンパイルエラーとなる。
とはいえ処理が重くなりがちなスクリプト言語において@Typedを付けるだけで手軽に最適化が行われるのは個人的には嬉しい。
何万回も呼ばれるような処理は@Typedを付けて高速に処理し、それ以外の場所では通常のスクリプトのように柔軟に書くといったことも出来ると思うので使いどころを考えながらもう少し試してみたいと思う。
Groovy++計測(1)
Groovyのスクリプトを静的型付をしてくれるらしい。
ソースコードに@Typedを指定すると静的な型に基づいて最適化されるっぽい。
フィボナッチでちょっと試してみた
@Typed int fib(int n) { return n < 2 ? 1 : fib(n - 1) + fib(n - 2); } int fib2(int n) { return n < 2 ? 1 : fib2(n - 1) + fib2(n - 2); } println 'Groovy++ Fibonachi Numbers(36) took '+(System.currentTimeMillis() - start)+"ms" start = System.currentTimeMillis() fib2(36) println 'Groovy Fibonachi Numbers(36) took '+(System.currentTimeMillis() - start)+"ms"
出力結果
$ groovy fib.groovy Groovy++ Fibonachi Numbers(36) took 156ms Groovy Fibonachi Numbers(36) took 8031ms
結果だけ見れば50倍ぐらい違う。
goovycでコンパイルしたコードを覗いてみる。( 一部抜粋)
public int fib(int n) { if (n < 2) return 1; return fib(n - 1) + fib(n - 2); } public int fib2(int n) { CallSite[] arrayOfCallSite = $getCallSiteArray(); if )((!BytecodeInterface8.isOrigZ())( || (__$stMC) || (BytecodeInterface8.disabledStandardMetaClass())() return DefaultTypeTransformation.intUnbox(ScriptBytecodeAdapter.compareLessThan)((Integer)DefaultTypeTransformation.box(n), (Integer)DefaultTypeTransformation.box(2))( ? (Integer)DefaultTypeTransformation.box(1) : arrayOfCallSite[15].call(arrayOfCallSite[16].callCurrent(this, arrayOfCallSite[17].call)((Integer)DefaultTypeTransformation.box(n), (Integer)DefaultTypeTransformation.box(1))(), arrayOfCallSite[18].callCurrent(this, arrayOfCallSite[19].call)((Integer)DefaultTypeTransformation.box(n), (Integer)DefaultTypeTransformation.box(2))())(); else return DefaultTypeTransformation.intUnbox)((n < 2 ? 1 : 0) != 0 ? (Integer)DefaultTypeTransformation.box(1) : (Integer)DefaultTypeTransformation.box(fib2(n - 1) + fib2(n - 2))(); return 0; }
これを見ると納得。ちょっと小難しい処理では差が出てますが単純なループ処理等でも測ってみたいと思います。
参考
http://www.slideshare.net/touchezdubois/groovypp-attack-6229953