Измерьте время выполнения для Java-метода

Как рассчитать время, затраченное на выполнение метода в Java?

Ответ 1

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


Из книги "Производительность платформы Java: стратегии и тактика":

С System.currentTimeMillis()

class TimeTest1 {
   public static void main(String[] args) {

      long startTime = System.currentTimeMillis();

      long total = 0;
      for (int i = 0; i < 10000000; i++) {
         total += i;
      }

      long stopTime = System.currentTimeMillis();
      long elapsedTime = stopTime - startTime;
      System.out.println(elapsedTime);
   }
}

С классом StopWatch

Вы можете использовать этот класс StopWatch и вызывать start() и stop до и после метода.

class TimeTest2 {
   public static void main(String[] args) {

      Stopwatch timer = new Stopwatch().start();

      long total = 0;
      for (int i = 0; i < 10000000; i++) {
         total += i;
      }

      timer.stop();
      System.out.println(timer.getElapsedTime());
   }
}

Смотрите здесь.


Профилировщик NetBeans:

Application Performance Application

Профили производительности процессор уровня производительность (время выполнения). Ты можешь выбрать профиль для всего приложения или части приложение.

Смотрите здесь.

Ответ 2

Чтобы быть более точным, я использовал бы метод nanoTime(), а не currentTimeMillis():

long startTime = System.nanoTime();
myCall(); 
long stopTime = System.nanoTime();
System.out.println(stopTime - startTime);

В Java 8 (выходной формат ISO-8601):

Instant start = Instant.now();
Thread.sleep(63553);
Instant end = Instant.now();
System.out.println(Duration.between(start, end)); // prints PT1M3.553S

Guava Stopwatch:

Stopwatch stopwatch = Stopwatch.createStarted();
myCall();
stopwatch.stop(); // optional
System.out.println("Time elapsed for myCall() is "+ stopwatch.elapsed(MILLISECONDS));

Ответ 3

Проверьте это: System.currentTimeMillis.

С помощью этого вы можете рассчитать время своего метода, выполнив:

long start = System.currentTimeMillis();
class.method();
long time = System.currentTimeMillis() - start;

Ответ 5

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

Если вы используете Spring, просмотрите класс MethodInterceptor.

Ответ 6

Если вы в настоящее время пишете приложение, то ответ на использование System.currentTimeMillis или System.nanoTime служат цели, указанной выше.

Но если вы уже написали код и не хотите его менять, лучше использовать перехватчики методов Spring. Например, ваша служба:

public class MyService { 
    public void doSomething() {
        for (int i = 1; i < 10000; i++) {
            System.out.println("i=" + i);
        }
    }
}

Чтобы избежать изменения службы, вы можете написать свой собственный метод перехватчика:

public class ServiceMethodInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = methodInvocation.proceed();
        long duration = System.currentTimeMillis() - startTime;
        Method method = methodInvocation.getMethod();
        String methodName = method.getDeclaringClass().getName() + "." + method.getName();
        System.out.println("Method '" + methodName + "' took " + duration + " milliseconds to run");
        return null;
    }
}

Также существуют API-интерфейсы с открытым исходным кодом, доступные для Java, например. BTrace. или профилировщиком Netbeans, как было предложено выше @bakkal и @Saikikos. Спасибо.

Ответ 7

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

long start1 = System.nanoTime();
// maybe add here a call to a return to remove call up time, too.
// Avoid optimization 
long start2 = System.nanoTime();
myCall(); 
long stop = System.nanoTime();
long diff = stop - 2*start2 + start1;

System.out.println(diff + " ns");

Кстати, вы будете измерять разные значения для одного и того же вызова из-за

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

Ответ 8

Нанотиме на самом деле не очень полезно в течение прошедшего времени, потому что оно значительно отличается от текущегоTimeMillis. Кроме того, nanotime имеет тенденцию обеспечивать чрезмерную точность за счет точности. Поэтому он крайне несовместим и нуждается в уточнении.

Для любого процесса измерения времени currentTimeMillis (хотя и почти так же плохо) делает лучше с точки зрения точности и точности балансировки.