越です。
最近すごく暑さが気になってきたので、夏休みを利用して、地元の長野で避暑地でも行ってゆっくりしようかと考えています。
scalaでベンチマーク
scalaの勉強のためにscalaでベンチマークを測る方法を調べていて、
scala.testing.BenchmarkがScala 2.11で廃止されていたのでsbt-jmhを試しに使ってみました。
Deprecate unmaintained/old classes for removal in 2.11
sbt-jmhを試すために作成したディレクトリ構成
. ├── build.sbt ├── project │ └── plugins.sbt └── src └─ main └─ scala └─ practiceJmh └─ Practice.scala
sbt 定義ファイルを設定
githubのREADMEを参考にsbt 定義ファイルを設定
build.sbt
enablePlugins(JmhPlugin)
project/plugins.sbt
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.1")
使い方
src/main/scala 配下の任意の .scala ファイルにクラスを作って、@Benchmarkをつけるだけ。
src/main/scala/practiceJmh/Practice.scala
package practiceJmh import org.openjdk.jmh.annotations.Benchmark import scala.collection._ class Practice { @Benchmark def useMapJmh(): Seq[String] = { useMap(10000) } @Benchmark def useBreakOutJmh(): Seq[String] = { useBreakOut(10000) } @Benchmark def useWhileJmh(): Seq[String] = { useWhile(10000) } def useMap(x: Int): Seq[String] = { 1.to(x).map(x => s"Hello World! $x") } def useBreakOut(x: Int): Seq[String] = { 1.to(x).map(x => s"Hello World! $x")(breakOut): Seq[String] } def useWhile(x: Int): Seq[String] = { var result: List[String] = List.empty val i = 1.to(x).iterator while(i.hasNext){ result = s"Hello World! ${i.next}" :: result } result.reverse.toSeq } }
ベンチマークの実行
プロジェクトのベースディレクトリで、sbt をコマンドライン引数なしで実行し、インタラクティブモードで起動する。
sbt
コンパイルする。
jmh:compile
実行する。
jmh:run -i 3 -wi 3 -f1 -t 1
オプション | 意味 |
---|---|
i | 計測回数 |
wi | ウォーミングアップ回数 |
f | 全体(計測回数+ウォーミングアップ回数)の試行回数 |
t | スレッド数 |
実行結果
[info] # Run complete. Total time: 00:00:19 [info] [info] Benchmark Mode Cnt Score Error Units [info] practiceJmh.Practice.useBreakOutJmh thrpt 3 549.210 ± 474.347 ops/s [info] practiceJmh.Practice.useMapJmh thrpt 3 588.116 ± 260.384 ops/s [info] practiceJmh.Practice.useWhileJmh thrpt 3 523.784 ± 359.510 ops/s
デフォルトではthrp(スループット)なので、Scoreは単位時間あたりの実行回数が表示されている(数字が大きいほうが良い)。 ただ、Error(誤差の範囲)が大きいので、計測回数とウォーミングアップ回数を増やして、再実行してみます。
jmh:run -i 30 -wi 10 -f1 -t 1
[info] # Run complete. Total time: 00:02:02 [info] [info] Benchmark Mode Cnt Score Error Units [info] practiceJmh.Practice.useBreakOutJmh thrpt 30 588.744 ± 34.702 ops/s [info] practiceJmh.Practice.useMapJmh thrpt 30 628.154 ± 13.763 ops/s [info] practiceJmh.Practice.useWhile thrpt 30 618.311 ± 15.134 ops/s
Error(誤差の範囲)が小さくなりました。
参考サイト
Micro Benchmark in Scala - Using sbt-jmh ScalaでtoSetやtoListとかを使うよりはbreakOutした方が少し速い