Как рассчитать скорость выполнения программы Java



Извините, если это звучит как глупый вопрос, но как вы время выполнения программы Java? Я не уверен, какой класс я должен использовать для этого.



Я ищу что-то вроде:



//Some timer starts here
for (int i = 0; i < length; i++) {
// Do something
}
//End timer here

System.out.println("Total execution time: " + totalExecutionTime);


спасибо

530   11  

11 ответов:

final long startTime = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
  // Do something
}
final long endTime = System.currentTimeMillis();

System.out.println("Total execution time: " + (endTime - startTime) );

надеюсь, что это помогло.

имейте в виду, что есть некоторые вопросы, где System#nanoTime() не может быть надежно использован на многоядерных процессорах для записи прошедшего времени ... каждое ядро имеет поддерживает свой собственный TSC ( Счетчик Времени): этот счетчик используется для получения времени nano (на самом деле это количество тиков с момента загрузки процессора).

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

Я наблюдал это некоторое время назад на AMD/Solaris, где время между двумя точками синхронизации иногда возвращалось как отрицательные значения, так и неожиданно большие положительные числа. Там был патч ядра Solaris и настройки BIOS, необходимые для форсирования AMD PowerNow! выкл, который, казалось, решил ее.

кроме того, есть (AFAIK) до сих пор не исправлена ошибка при использовании java System#nanoTime() в среде VirtualBox; вызывая всевозможные причудливые прерывистые проблемы с потоками для нас как можно больше java.util.concurrency пакет полагается на nano времени.

Читайте также:

Система.nanoTime() совершенно бесполезно? http://vbox.innotek.de/pipermail/vbox-trac/2010-January/135631.html

Вы можете использовать System#nanoTime(). Получить его до и после выполнения и просто сделать математику. Это предпочтительнее выше System#currentTimeMillis() потому что он имеет более высокую точность. В зависимости от используемого оборудования и платформы вы можете получить неверный промежуток времени. Здесь с Core2Duo на Windows, между примерно 0 и ~15 МС на самом деле ничего не может быть вычислено.

более продвинутый инструмент является профайлер.

вы получаете текущее системное время в миллисекундах:

final long startTime = System.currentTimeMillis();

затем вы делаете то, что вы собираетесь делать:

for (int i = 0; i < length; i++) {
  // Do something
}

тогда вы видите, сколько времени это заняло:

final long elapsedTimeMillis = System.currentTimeMillis() - startTime;

для простых вещей,

С помощью AOP / AspectJ и @Loggable аннотации jcabi-аспекты вы можете сделать это легкий и компактный:

@Loggable(Loggable.DEBUG)
public String getSomeResult() {
  // return some value
}

каждый вызов этого метода будет отправлен в slf4j logging facility с DEBUG уровень ведения журнала. И каждое сообщение журнала будет включать время выполнения.

посмотреть System.currentTimeMillis().

использовать долго startTime=System.currentTimeMillis() по времени начала, в верхней части петли

поставить long endTime= System.currentTimeMillis(); вне конца цикла. Вам придется вычесть значения, чтобы получить время выполнения в миллисекундах.

Если вы хотите время в наносекундах, проверить System.nanoTime()

вы также можете попробовать Perf4J. Its аккуратный способ делать то, что вы ищете, и помогает в агрегированной статистике производительности, как среднее, минимальное, максимальное, стандартное отклонение и транзакций в секунду в течение установленного промежутка времени. Выдержка из http://perf4j.codehaus.org/devguide.html:

StopWatch stopWatch = new LoggingStopWatch();

try {
    // the code block being timed - this is just a dummy example
    long sleepTime = (long)(Math.random() * 1000L);
    Thread.sleep(sleepTime);
    if (sleepTime > 500L) {
        throw new Exception("Throwing exception");
    }

    stopWatch.stop("codeBlock2.success", "Sleep time was < 500 ms");
} catch (Exception e) {
    stopWatch.stop("codeBlock2.failure", "Exception was: " + e);
}

выход:

INFO: start[1230493236109] time[447] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493236719] time[567] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493237286] time[986] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493238273] time[194] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238467] time[463] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238930] time[310] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239241] time[610] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493239852] time[84] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239937] time[30] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239968] time[852] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
public class someClass
{
   public static void main(String[] args) // your app start point
   {
       long start = java.util.Calendar.getInstance().getTimeInMillis();

       ... your stuff ...

       long end = java.util.Calendar.getInstance().getTimeInMillis();
       System.out.println("it took this long to complete this stuff: " + (end - start) + "ms");
   }
}

Использование Системы.currentTimeMillis () - это правильный способ сделать это. Но, если вы используете командную строку, и вы хотите, чтобы время всей программы примерно и быстро, подумайте о:

time java App

что позволяет не изменять код и время ваше приложение.

Comments

    Ничего не найдено.