I am using jmh to compare the performance of several methods that print a lot to the console. In fact, these are different solutions of a fizzbazz problem.
Each implementation of fizzbuzz is a class that implements the FizzBazz interface and has a print() method. All these implementations are compiled into a separate jar.
I am trying to suppress output of this method in my benchmarks. Thus, I need to replace the output stream with an array before running the benchmarks, and return it back after they finish.
If I do this inside each benchmark method, like this:
@Benchmark
public void naiveTest() {
PrintStream originalOut = System.out;
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
System.setOut(new PrintStream(outContent));
new NaiveFizzBuzz().print(N); // N is upper limit
System.setOut(originalOut);
}
then everything works fine. But this is a bunch of repetitive code, and I don't want to get rid of it. Besides, this code breaks measurements, as it is called every time the test is run.
I'm trying to use state for my task.
@State(Scope.Benchmark)
public static class MyState {
private PrintStream originalOut;
@Setup
public void doSetup() {
originalOut = System.out;
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
System.setOut(new PrintStream(outContent));
}
@TearDown
public void doTearDown() {
System.setOut(originalOut);
}
}
And my benchmarks looks like this:
@Benchmark
public void naiveTest() {
new NaiveFizzBuzz().print(N);
}
// Lots of similar benchmarks here...
But it doesn't work.
How can I put all the code for replacing the output stream in one place so that it is automatically executed before each test run?
I found a solution to my problem. It consists in the fact that I need to pass my state object as an argument to each benchmark.
@Benchmark
public void naiveTest(MyState state) {
new NaiveFizzBuzz().print(N);
}
works exactly as i need.
Unfortunately, the documentation of jmh is not very user-friendly, so it took me a while to find this point.
I have done a little research and I have come to the conclusion that it is OK to answer my own question. Please correct me if this is not the case. Then I'll edit the question.