-
-
Notifications
You must be signed in to change notification settings - Fork 2
How It Works
Note: this is still mostly correct, but as of version 0.4.0
, all benchmarks are compiled into a single class.
It is recommended that you first understand how JMH works when used from Java, and have read the examples in the sample file before reading this. Also note that understanding the internals is not important for general usage.
For each :benchmarks
element and :states
key, a separate class file is generated. Benchmark :options
translate to JMH benchmark annotations, and :params
are compiled as state class instance fields.
For example, the following data:
{:benchmarks [{:fn some.ns/foo, :args [:state/bar]}]
:states {:bar {:fn some.ns/bar, :args [:param/quux]}}
:params {:quux {:data 42}}}
is compiled into the following two classes, which we'll represent with some Java code. The identifiers prefixed with $
represent unique generated names:
package $jmh;
import clojure.lang.IFn;
import org.openjdk.jmh.annotations.*;
import static io.github.jgpc42.jmh.Util.*;
public class $Foo {
private static final IFn _fn = resolve("some.ns", "foo");
@Benchmark
public final Object run ($Bar state) {
return _fn.invoke(state._value);
}
}
package $jmh;
import clojure.lang.IFn;
import org.openjdk.jmh.annotations.*;
import static io.github.jgpc42.jmh.Util.*;
@State(Scope.Benchmark)
public class $Bar {
private static final IFn _trial_setup_fn = resolve("some.ns", "bar");
@Param({"{:data 42}"})
private String $_param_quux;
public Object _value;
@Setup(Level.Trial)
public final void trial_setup () {
Object arg = read($_param_quux);
_value = _trial_setup_fn.invoke(arg);
}
}
Note that JMH expects state value and parameter fields to be non-final
, and is responsible for maintaining thread-safe access. Also, the public
state value fields are only ever accessed from benchmark and state fixture methods in the generated code.
The above is a somewhat simplified view, but is conceptually accurate. Other considerations include whether some.ns/foo
takes or returns primitive values, uses parameters or JMH infrastructure arguments, is to be apply
-ed, etc.