Тестирование производительности Java [дубликат]

48
задан Chris W. 25 October 2017 в 12:48
поделиться

9 ответов

Один дефект в том подходе - то, что "реальное" время doSomething() берет для выполнения, может варьироваться дико в зависимости от того, что другие программы работают на системе и какова ее загрузка. Это делает измерение производительности несколько неточным.

Еще один точный способ отследить время это берет для выполнения кода, предполагая, что код является однопоточным, должен посмотреть на процессорное время, использованное потоком во время вызова. Можно сделать это с классами JMX; в частности, с ThreadMXBean . Можно получить экземпляр ThreadMXBean от java.lang.management.ManagementFactory , и, если поддержка платформ он (большинство делает), используйте getCurrentThreadCpuTime метод вместо System.currentTimeMillis, чтобы сделать подобный тест. Примите во внимание что getCurrentThreadCpuTime время отчетов в наносекундах, не миллисекунды.

Вот образец (Scala) метод, который мог использоваться для выполнения измерения:

def measureCpuTime(f: => Unit): java.time.Duration = {

  import java.lang.management.ManagementFactory.getThreadMXBean
  if (!getThreadMXBean.isThreadCpuTimeSupported)
    throw new UnsupportedOperationException(
      "JVM does not support measuring thread CPU-time")

  var finalCpuTime: Option[Long] = None
  val thread = new Thread {
    override def run(): Unit = {
      f
      finalCpuTime = Some(getThreadMXBean.getThreadCpuTime(
        Thread.currentThread.getId))
    }
  }
  thread.start()

  while (finalCpuTime.isEmpty && thread.isAlive) {
    Thread.sleep(100)
  }

  java.time.Duration.ofNanos(finalCpuTime.getOrElse {
    throw new Exception("Operation never returned, and the thread is dead " +
      "(perhaps an unhandled exception occurred)")
  })
}

(Не стесняются переводить вышеупомянутое в Java!)

Эта стратегия не прекрасна, но она меньше подвергается изменениям в системной нагрузке.

33
ответ дан Chris W. 7 November 2019 в 12:42
поделиться

Код, показанный в вопросе, не является хорошим кодом измерения производительности:

  1. компилятор мог бы принять решение оптимизировать Ваш код путем переупорядочения операторов. Да, это может сделать это. Это означает, что Ваш весь тест мог бы перестать работать. Это может даже принять решение встроить метод под тестом и переупорядочить имеющие размеры операторы в теперь встроенный код.

  2. горячая точка могла бы принять решение переупорядочить Ваши операторы, встроенный код, результаты кэша, выполнение задержки...

  3. Даже принятие компилятора/горячей точки не обманывало Вас, что Вы измеряете, "стенное время". То, что необходимо измерять, является процессорным временем (если Вы не используете ресурсы ОС и хотите включать их также, или Вы измеряете соревнование блокировки в многопоточной среде).

решение? Используйте настоящего профилировщика. Существуют много вокруг, и свободные профилировщики и демонстрации / заблокированные временем пробные версии силы рекламы.

16
ответ дан Ran Biron 7 November 2019 в 12:42
поделиться

Используя Java Профилировщик является наилучшим вариантом, и он даст Вам все понимание, в котором Вы нуждаетесь в код. то есть Время отклика, Поток CallTraces, Использования памяти, и т.д.

я предложу Вас JENSOR, Профилировщик Java с открытым исходным кодом, для его простоты в употреблении и никаких издержек на ЦП. Вы можете загрузить его, оснастить код и получите всю информацию, в которой Вы нуждаетесь о своем коде.

можно загрузить его с: http://jensor.sourceforge.net /

3
ответ дан M.N 7 November 2019 в 12:42
поделиться

Следует иметь в виду, что разрешение System.currentTimeMillis() варьируется между различными операционными системами. Я полагаю, что Windows составляет приблизительно 15 мс. Таким образом, если Ваш doSomething() выполнения быстрее, чем разрешение времени, Вы получите дельту 0. Вы могли работать doSomething() в цикле многократно, но тогда JVM может оптимизировать его.

1
ответ дан Steve Kuo 7 November 2019 в 12:42
поделиться

Хорошо это - всего одна часть тестирования производительности. В зависимости от вещи Вы тестируете Вас, вероятно, придется посмотреть на размер "кучи", количество потока, сетевой трафик или большое количество других вещей. Иначе я использую ту технику для простых вещей, которые я просто хочу видеть, сколько времени они берут для выполнения.

0
ответ дан Josh Harris 7 November 2019 в 12:42
поделиться

Это хорошо, когда Вы сравниваете одну реализацию с другим или пытаетесь найти медленную часть в своем коде (хотя это может быть утомительно). Это - действительно хорошая техника для знания, и Вы будете, вероятно, использовать его больше, чем кто-либо другой, но будете знакомы с профильным инструментом также.

0
ответ дан Bill K 7 November 2019 в 12:42
поделиться

Вы посмотрели на профильные инструменты в netbeans и затмение . Эти инструменты дают Вам лучший дескриптор на том, что ДЕЙСТВИТЕЛЬНО поднимает все время в Вашем коде. Я нашел проблемы, которые я не осознавал при помощи этих инструментов.

0
ответ дан Milhous 7 November 2019 в 12:42
поделиться

Я предположил бы, что Вы захотите к doSomething (), прежде чем Вы начнете синхронизировать также, так, чтобы код был JITted и "подогревший".

0
ответ дан Tim Cooper 7 November 2019 в 12:42
поделиться

Japex может быть полезен для Вас, или как способ быстро создать сравнительные тесты, или как способ изучить проблемы сравнительного тестирования в Java через исходный код.

0
ответ дан Rich Apodaca 7 November 2019 в 12:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: