Benchmark Inheritance

Aleksey Shipilev aleksey.shipilev at oracle.com
Thu Jun 23 17:37:01 UTC 2016


On 23.06.2016 12:41, Aleksey Shipilev wrote:
> You are caught in a very unlucky place with benchmark hierarchy,
> abstract classes, and @State DAGs. The problem goes like this:
> 
> IntProperty.getProperty(TxState txState):
>   implicit state: IntPropertyRead instance (this)
>   states: TxState
> 
> ...resolution continues:
> 
> TxState.setUp:
>   state: PropertyReadBenchmark
> 
> The underlying reason is that @State dependency matching machinery is
> oblivious of class hierarchies: IntPropertyRead and
> PropertyReadBenchmark are *distinct* states for it.

Thinking more about it, this is lesser of two evils.


> So it fails when PropertyReadBenchmark is abstract: it cannot be a
> @State on its own -- only its subclasses can be instantiated. The
> compiler would fail to produce an auxiliary JMH classes for
> PropertyReadBenchmark, without having all the abstract methods implemented.

This case should have better diagnostics (fixed):
 https://bugs.openjdk.java.net/browse/CODETOOLS-7901706


> It fails if make PropertyReadBenchmark non-abstract: the compilation
> will proceed, and the dependency matching machinery will feed the
> *PropertyReadBenchmark* instance into TxState.setUp, not the
> *IntPropertyRead* one. Of course, it you put exception into
> PropertyReadBenchmark.propertyDefinition, it would throw.

This is actually a correct behavior: we should keep matching by class
name, regardless if there are classes that can be substituted for each
other. This eliminates nasty ambiguities, e.g.:

  @State
  public class State1 {}

  @State
  public class State2 extends State1 {}

  @Benchmark
  public void test(State1 s1, State2 s2) {
    assert (s1 instanceof State1); // oops, can use State2 here?
    assert (s2 instanceof State2);
  }

Thanks,
-Aleksey






More information about the jmh-dev mailing list