Skip to content

JMH Testing with Scala

2018-02-22 Discuss

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()) }

} ```