JMH で何かしらの処理のパフォーマンスを計測する時に、すべての計測対象が必ずしもステートレスにできないケースがある。
例えば、 List<String>
にデータが 1万レコードほどある時に、 add(int, String)
の呼び出しのパフォーマンスを計測する場合など。
この例の場合だと、 JMH の実行設定をイテレーション10秒に設定していると、 3 億回ほどメソッドが呼び出されたりする。すると、最後の方には List<String>
にデータが 3億1 万レコードある状態でのベンチマークとなり、もともと計測したかった 1万レコードの時点での速度計測にならなかったりする。
このようなケースでは、 @Setup
と @TearDown
アノテーションに与える、 Level
をうまく設定してやることで、レコード件数を維持できる。
@State(Scope.Group) public class Sample { private List<String> list; @Group("sample") @Setup(Level.Iteration) public void setup() { this.list = new ArrayList<>(); for (int i = 0; i < 10_000; i++) { list.add(Util.randomString()); } } @Group("sample") @Benchmark @BenchmarkMode(Mode.Throughput) public void addOp() { list.add(Util.randomString()); } @Group("sample") @TearDown(Level.Invocation) public void teardown() { list.remove(list.size() - 1); } }