2013-11-21 3 views
2

У меня было количество запросов, выполняемых моим java-кодом. Для каждого запроса мне нужно контролировать время выполнения. Более того, мне также необходимо контролировать время выполнения определенных функций. Итак, есть ли способ сделать это элегантным способом?Мониторинг производительности Java

+1

Запрашивать предложения по библиотеке явно не по теме, извините. – Zong

ответ

2

Для этого есть проект с открытым исходным кодом. Вот пример фрагмента кода из него.

private final static int BASIC_STOPWATCH_ID = 
    Audits.mapAudit("example.basicStopwatch"); 

    public void tryOut(){ 
    final Stopwatch stopwatch = Audits.getBasicStopwatch(BASIC_STOPWATCH_ID); 
    stopwatch.start(); 
    doSomeWork(); 
    stopwatch.stop(); 
    } 

Caudit находится на github.

+0

С помощью Jprofiler или других инструментов вы можете просто следить за временем. С Caudit вы можете наблюдать навсегда. просто проверьте это. –

2

Perf4J - лучшее решение для этого.

Perf4J - это набор инструментов с открытым исходным кодом для добавления инструкций синхронизации времени на сервере Java и для ведения журнала, анализа и мониторинга результатов. Для тех разработчиков, которые знакомы с рамками лесозаготовительных, таких как log4j или java.util.logging, аналогия помогает описать Perf4J:

Perf4J является System.currentTimeMillis(), как log4j должен System.out.println()

для дальнейшей ссылки вы можете посетить http://www.infoq.com/articles/perf4j

0

Если вы хотите измерить время выполнения метода, вы можете также использовать System.nanoTime() метод Java. На котором используется таймер с наивысшим разрешением, доступный на вашей платформе. Время - относительное «свободное время», которое можно сравнить только с другими значениями nanoTime. (https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks)

Однако очень важно помнить, что Java требует значительного времени для «разогрева». Java запускает свой скомпилированный байт-код в JVM (виртуальная машина Java) и использует JIT (компилятор Just In Time) для оптимизации частей байт-кода во время выполнения, чтобы повысить производительность.

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

import java.util.Random; 
import tools.Helpers; 

public class DivideInlineShort { 
    public static void main(String[] args) { 
     int n = args.length > 0 ? Integer.parseInt(args[0]) : 10000; 
     Random r = new Random(); 
     for (int i = 0; i < 50; i++) 
      runTest(n, r.nextInt(8) + 1); // you need the random to prevent the JVM removing the loops 
    } 

    public static void runTest(int n, int ran) { 
     int counter = 0; 
     long timeStart = System.nanoTime(); 

     for (int j = 0; j < n; j++) 
      for (int i = ran; i < 100000 + ran; i++) 
       counter += return1(i); 

     long timeEnd = System.nanoTime(); 
     System.out.println(
      Helpers.roundedTimeInMillis(timeStart, timeEnd) + "\t\t" + counter); 
    } 

    public static int return1(int i) { 
     return i/i; 
    } 
} 

Первые 2 до 3 пробеги взял мою машину около 700 мс, в то время как остальные 47 были вокруг 370ms. Это можно объяснить из-за оптимизации inlining, которая срабатывает после того, как метод называется более 10.000 раз, если я правильно помню.

Так что, если вы хотите точно измерить время выполнения кода, вы должны запускать его несколько раз на одном экземпляре JVM и пренебрегать первыми несколькими раундами.

Смежные вопросы