Saturday, June 25, 2011

GBench = @Benchmark Annotation + BenchmarkBuilder

Groovy 用のベンチマーク・フレームワーク、 GBench をリリースしました。GBench は2つの機能、 @Benchmark Annotation と BenchmarkBuilder を持っています @Benchmark Annotation はプロダクトのコードをいじらずに実行時間を計測することを可能にするアノテーションで、既に公開されています。より詳しい情報については以前のポストを読んでください。 BenchmarkBuilder はベンチマーク・コードを簡単に書くための便利なビルダで、今回初めて登場します。

次のコードは文字列連結を1000回繰り返してベンチマークを採るものです:
----
def strings = ['GBench', ' = ', '@Benchmark Annotation', ' + ', 'BenchmarkBuilder']
def benchmark = new BenchmarkBuilder()
benchmark.run times: 1000, {
    with '+=', { 
        def s = ''
        for (string in strings) {
            s += string    
        }
    }
    with 'concat', { 
        def s = ''
        for (string in strings) {
            s.concat string    
        }
    }
    with 'string builder', {
        def sb = new StringBuilder()    
        for (string in strings) {
            sb << string    
        }
        sb.toString() 
    }
    with 'join', {
        strings.join()
    }
}
println benchmark
----

出力はこのようになります:
----
                   time
+=             18197705
concat          7669621
string builder  9420539
join            5248348
----

もちろん結果はソートできます:
----
println benchmark.sort({ lhs, rhs -> lhs.time <=> rhs.time })
----

----
                   time
join            5248348
concat          7669621
string builder  9420539
+=             18197705
----

結果を好きなように処理することもできます:
----
new File('benchmark.csv').withWriter { file ->
    file.writeLine 'label,time(ms)'
    benchmark.sort().each { bm ->
        file.writeLine "${bm.label},${bm.time / 1000000}"
    }
}
----

----
> cat benchmark.csv
label,time(ms)
join,5.248348
concat,7.669621
string builder,9.420539
+=,18.197705
----

いまのところ、GBench は wall-clock time しか計測できませんが、将来のリリースでは CPU time や user time もサポートする予定です。

GBench はこちらからダウンロードできます。ぜひ試してフィードバックしてください!

2 comments:

  1. とても素晴らしいです!
    grabで使える形だと利用者増えるかもですね~

    ReplyDelete
  2. ありがとうございます :-) そうですね、grabから使えるようにしますか。

    ReplyDelete