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

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

8 ответов

Чтобы быть более точным, я бы использовал 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

Гуава Секундомер:

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

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


Из книги "Производительность платформы 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:

Производительность приложения

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

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

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

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

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

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

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

Если вы используете Spring, взгляните на их класс MethodInterceptor.

Если вы в данный момент пишете приложение, то ответ заключается в использовании 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;
    }
}

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

Как предложено, nanoTime () очень точен на коротких временных масштабах. Когда требуется такая точность, вам нужно позаботиться о том, что вы действительно измеряете. Особенно, чтобы не измерить сам звонок 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 медленнее, чем без!))

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

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

Другие вопросы по тегам