JMH Testing with Scala
JMH is the Java Microbenchmark Harness provided by the OpenJDK project. It can be a useful tool for validating assumptions about the performance of small code sections subject to many iterations.
See the following links for more details:
Gradle¶
A Gradle plugin is available for JMH.
Project layout:
.
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
└── jmh
└── scala
└── io
└── github
└── brharrington
├── AtomicLongUpdate.scala
├── CurrentTimeMillis.scala
├── NanoTime.scala
└── TimeLimiting.scala
The build.gradle configuration:
``` plugins { id 'scala' id 'idea' id 'me.champeau.gradle.jmh' version '0.4.5' }
repositories { jcenter() }
dependencies { compile 'com.netflix.servo:servo-core:0.12.17' compile 'org.scala-lang:scala-library:2.12.4' }
idea { module { testSourceDirs += sourceSets.jmh.scala.srcDirs } } ```
Run the tests:
./gradlew jmh
sbt¶
An sbt plugin is available for JMH.
Example project layout:
.
├── build.sbt
├── project
│ ├── build.properties
│ ├── plugins.sbt
│ ├── sbt
│ └── sbt-launch-1.0.0.jar
└── src
└── main
└── scala
└── io
└── github
└── brharrington
├── AtomicLongUpdate.scala
├── CurrentTimeMillis.scala
├── NanoTime.scala
└── TimeLimiting.scala
The build.sbt configuration:
``` name := "misc-jmh"
organization := "io.github.brharrington"
scalaVersion := "2.12.4"
enablePlugins(JmhPlugin)
libraryDependencies ++= Seq( "com.netflix.servo" % "servo-core" % "0.12.17" ) ```
The plugins.sbt configuration:
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.27")
Run the tests:
./project/sbt jmh:run
Example Test Class¶
``` package io.github.brharrington
import java.util.concurrent.atomic.AtomicLong
import org.openjdk.jmh.annotations.Benchmark import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.State import org.openjdk.jmh.infra.Blackhole
@State(Scope.Thread) class AtomicLongUpdate {
private val value = new AtomicLong()
@Benchmark def incrementAndGet(bh: Blackhole): Unit = { bh.consume(value.incrementAndGet()) }
@Benchmark def addAndGet(bh: Blackhole): Unit = { bh.consume(value.addAndGet(42)) }
@Benchmark def get(bh: Blackhole): Unit = { bh.consume(value.get()) }
} ```