Search code examples
jmh

How do I have different initialization (setup) methods for different tests in JMH?


I'm writing a JMH test to compare two different implementations. So I have something like:

Counter c1;
Counter c2;

@Setup
public void setup() {
    c1 = new Counter1();
   c2 = new Counter2();
}

@Benchmark
public int measure_1_c1() {
    return measure(c1);
}

@Benchmark
public int measure_2_c2() {
    return measure(c2);
}

Each test will run in its own forked JVM. The issue is that it takes a lot of setup in the constructor for each operation (and I have about 20 of then). So what I'd like to do in my @Setup method is to initialize only the one that will be used depending on the test being run in this forked JVM.

Is there a way to do that?


Solution

  • Yes, you need separate @State objects and reference them as needed. For example:

    @State
    public static class State1 {
        int x;
    
        @Setup
        void setup() { ... }
    }
    
    @State
    public static class State2 {
        int y;
    
        @Setup
        void setup() { ... }
    }
    
    @Benchmark
    public int measure_1(State1 s1) {
        // Only s1 @Setup have run
        // use s1.x...
    }
    
    @Benchmark
    public int measure_2(State2 s2) {
        // Only s2 @Setup have run
        // use s2.y...
    }
    
    @Benchmark
    public int measure_3(State1 s1, State2 s2) {
        // s1 and s2 @Setups have run
        // use s1.x, s2.y...
    }