Предположим, у нас есть метод со следующими аннотациями:
Код: Выделить всё
@Benchmark
@Fork(value = 1, warmups = 0)
@Measurement(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS)
Мы делим затраченное время на вызовы.
Это дает среднее время на один вызов.
Если я использую @BenchmarkMode(Mode.Throughput), мы делим количество завершенных вызовов за истекшее время.
Это дает нам пропускную способность.
Предположим, у нас есть тестовый класс с состоянием Foo:
Код: Выделить всё
@State(Scope.Benchmark)
internal open class FooBenchmark {
class Foo {
private val values = mutableListOf()
fun add() = values.add(values.size.toString())
fun size() = values.size
}
private var foo = Foo()
@Setup(Level.Invocation)
fun eachInvocation() {
foo = Foo()
}
@Benchmark
@Fork(value = 1, warmups = 0)
@Measurement(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS)
@BenchmarkMode(Mode.SingleShotTime)
fun fooBenchmark(hole: Blackhole) {
check(foo.size() == 0)
foo.add()
check(foo.size() == 1)
hole.consume(foo)
}
}
Но для меня, для SingleShotTime, JMH вызывает метод fooBenchmark несколько раз.
1 ответвление, 1 итерация, но несколько вызовов.
И он использует один и тот же экземпляр. класса FooBenchmark в разных потоках.
Это приводит к конфликту при доступе к состоянию foo.
Это всего лишь пример того, как определенно происходят множественные вызовы. Мне НЕ нужен доступ к данным из разных потоков.
Я не понимаю, как работает каждый из режимов JMH? Или я неправильно настроил режим SingleShotTime?
Подробнее здесь: https://stackoverflow.com/questions/798 ... in-java-mi
Мобильная версия