Как рассчитать время, затраченное на выполнение метода в 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;
Ответ 4
Если вы разрабатываете приложения для Android, вы должны попробовать TimingLogger
класс.
Взгляните на эти статьи, описывающие использование вспомогательного класса TimingLogger
:
- Измерение производительности в Android SDK (27.09.2010)
- Обнаружение Android API - часть 1 (03.01.2017)
Ответ 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 (хотя и почти так же плохо) делает лучше с точки зрения точности и точности балансировки.