Eclipseでのインポート編成

EclipseJAVAコードを編集するのにインポートの編成(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が快適になりました。

アジャイルプラクティス

先月末に「アジャイルプラクティス」を読んでみた。

アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣

アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣

ここで書かれている事はアジャイルに関わらず「そうだよなぁ」と思うことが多い。
いくつもの本を読んでみても実践しなければ結局身にはならない。
アジャイルの手法自体は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

Lionさん

iMacをアップデートしました。
細かいところで変わってますね。
まだまだ触り始めたところなので特に不具合等もありませんが、これでxcodeの最新版が使えるのでiPhoneアプリでも作ろうかなと思ってます。

何を作るのかまずはネタ探しですけど(^^;;

基本情報処理試験

えーと、この業界に入って丸9年ほど経つのですか、資格というものを全く取っていません。

しかし、資格取得の報酬が下がるとの事なので、慌てて試験に申し込みました。

周囲の対策しなくても余裕でしょ!的なプレッシャーのため、なんとかせにゃあかんと思い立ち過去問用のiPhoneアプリを購入。

結局全部は解けていないまま一夜漬けモード。
よし、今日こそ試験勉強。。。
休出で仕事。。。

ほんとに一夜漬けで試験に臨みます。
果たして合否はどうなる事か。