2010-03-31 2 views
35

У меня есть программа, которую я сам написал в java, но я хочу проверить время выполнения метода и получить тайминги для определенных методов. Мне было интересно, возможно ли это, возможно, каким-то образом подключаемый модуль eclipse? или, возможно, вставить какой-то код?Как я могу проверить время выполнения метода в java?

Я вижу, это довольно маленькая программа, не более 1500 строк, которая была бы лучше выделенного инструмента или System.currentTimeMillis()?

Большое спасибо

+3

Вы должны использовать 'System.nanoTime()' для измерения * истекшее время * (см http://stackoverflow.com/questions/238920/quick-question-java-system-clock/ 239661 # 239661), а не 'System.currentTimeMillis()'. Другие пункты (разминка, JIT), упомянутые @Stephen в комментарии, остаются в силе. –

+1

Используйте класс секундомера для этой задачи –

ответ

35

Другие, чем при использовании профилировщика, простой способ получить то, что вы хотите следующее:

public class SomeClass{ 
    public void somePublicMethod() 
    { 
     long startTime = System.currentTimeMillis(); 
     someMethodWhichYouWantToProfile(); 
     long endTime = System.currentTimeMillis(); 
     System.out.println("Total execution time: " + (endTime-startTime) + "ms"); 
    } 
} 
+0

@ Stephen C - справедливые точки. Вышеупомянутый метод, который я использую, прежде всего, при попытке получить быстрое представление об эффективности метода. Мои требования в большинстве случаев не нужны для точности миллисекунд. –

+1

Возможно, я хочу добавить к этому ответу, что вы можете принять во внимание разминку. С помощью флага '-XX: CompileThreshold = 100' вы вынуждаете JVM скомпилировать ваш метод к собственному коду, когда он был выполнен 100 раз. Таким образом, вы можете выполнить его 100 раз без времени. После этого его скомпилировали в собственный код, и вы могли бы правильно его измерить. –

+0

Есть ли способ компенсировать время, необходимое для вызова метода? Например, я не хочу подсчитывать время, необходимое для копирования параметров, и адрес возврата, который нужно указать и т. Д. – Celeritas

2

Вы должны использовать профайлер как

Они будут легко интегрироваться с любой IDE и показать все, что деталь вам нужно.

Конечно, эти инструменты сложны и предназначены для использования в сложных программах, если вам нужны только некоторые простые тесты, я предлагаю вам использовать System.currentTimeMillis() или System.nanoTime() и рассчитать дельта миллисекундов между вызовами самостоятельно.

+0

Понимаю, это довольно маленькая программа, не более 1500 строк, что было бы лучше выделенного инструмента или System.currentTimeMillis()? – KP65

+0

Если вам просто нужно проверить, как быстро некоторые методы выполняют работу с __System.currentTimeMillis() __, но помните, что это не совсем точно! У вас может быть квантование десятых миллисекундов и аналогичные проблемы. Профилирование - это гораздо лучший способ сделать то, что вам нужно сделать, но для этого требуется немного обучения. – Jack

1

Вы можете добавить этот код, и он скажет вам, сколько времени потребовалось выполнить методу.

long millisecondsStart = System.currentTimeMillis(); 
executeMethod(); 
long timeSpentInMilliseconds = System.currentTimeMillis() - millisecondsStart; 
+10

Три проблемы. 1) миллисекундное время может быть квантовано; например до 20 мс. 2) вы фактически измеряете время 'executeMethod()' + время 'System.currentTimeMillis()'. 3) это не учитывает эффекты прогрева JVM; например JIT сборник. –

1

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

Я использую VisualVM. скользкий и простой.

1

Jprofiler и yourkit хороши, но стоят денег.

Существует бесплатный плагин для eclispe под названием TPTP (тест Performance Tools Platform), который может дать вам время выполнения кода. Вот учебник, в котором рассказывается о быстром поиске google. http://www.eclipse.org/articles/Article-TPTP-Profiling-Tool/tptpProfilingArticle.html

0

Другого выполненное на заказ решения может быть основан на следующем сообщении: http://www.mkyong.com/spring/spring-aop-examples-advice/

Вы затем также возможность использовать утилиты вокруг мониторинга приложений & Snmp. Если вам необходимо регулярно «набирать» свои методы в производственной среде, вы, вероятно, должны рассмотреть возможность использования одного из тех инструментов SNMP.

1

Google Guava has a stopwatch, делает вещи простыми и легкими.

Stopwatch stopwatch = Stopwatch.createStarted(); 
myFunctionCall(); 
LOGGER.debug("Time taken by myFunctionCall: " + stopwatch.stop()); 
14

Если узкое место достаточно большое, чтобы его можно было наблюдать с помощью профилировщика, используйте профилировщик.

Если вам нужна более высокая точность, лучшим способом измерения небольшого фрагмента кода является использование инфраструктуры микрообъектов Java, например OpenJDK's JMH или Google's Caliper. Я считаю, что они так же просты в использовании, как JUnit, и не только вы получите более точные результаты, но вы получите опыт сообщества, чтобы сделать все правильно.

Подписывается JMH microbenchmark для измерения времени выполнения Math.log():

private double x = Math.PI; 

@Benchmark 
public void myBenchmark() { 
    return Math.log(x) 
} 

Использование currentMillis() и nanoTime() для измерения имеет много ограничений:

  1. Они имеют задержку (они также требуют времени, чтобы выполнить), которые смещают ваши измерения.
  2. Они ОЧЕНЬ ограниченной точности, это означает, что вы можете MESURE вещей от 26ns к 26ns в Linux и 300 или так в Windows, описало here
  3. фазы прогрева не принимаются во внимание, что делает ваши измерения колеблются МНОГО.

В currentMillis() и nanoTime() методе в Java может быть полезна, но должна быть использована с EXTREME ВНИМАНИЯ или вы можете получить Неправильные ошибки измерений like this где порядок измеряемых фрагментов влияют на измерения или like this где автор ошибочно заключить что несколько миллионов операций, выполняемых менее чем за миллисекунду, когда на самом деле JMV не реализовал никаких операций, в которых был сделан и поднял код, вообще не выполняя никакого кода.

Вот замечательные видео, объясняющие, как microbenchmark правильного пути: https://shipilev.net/#benchmarking

3

Для быстрых и грязных тестов измерения времени, не использовать время от стены часы (System.currentTimeMillis()). Предпочитают System.nanoTime() вместо:

public static void main(String... ignored) throws InterruptedException { 
    final long then = System.nanoTime(); 
    TimeUnit.SECONDS.sleep(1); 
    final long millis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - then); 
    System.out.println("Slept for (ms): " + millis); // = something around 1000. 
} 
Смежные вопросы