Как рассчитать скорость выполнения Java-программ - PullRequest
79 голосов
/ 04 апреля 2010

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

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

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

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

Ответы [ 13 ]

127 голосов
/ 04 апреля 2010
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));
33 голосов
/ 04 апреля 2010

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

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

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

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

Смотри также:

Является ли System.nanoTime () полностью бесполезным? http://vbox.innotek.de/pipermail/vbox-trac/2010-January/135631.html

9 голосов
/ 04 апреля 2010

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

Более продвинутым инструментом является профилировщик .

7 голосов
/ 04 апреля 2010

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

final long startTime = System.currentTimeMillis();

Тогда ты делаешь то, что собираешься делать:

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

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

final long elapsedTimeMillis = System.currentTimeMillis() - startTime;
3 голосов
/ 04 апреля 2010

Для простых вещей System.currentTimeMillis () может работать.

На самом деле настолько часто, что моя IDE настроена так, что после ввода "t0" она генерирует следующую строку:

final long t0 = System.currentTimeMillis()

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

http://perf4j.codehaus.org/devguide.html

2 голосов
/ 19 января 2015

Используя AOP / AspectJ и @Loggable аннотацию из jcabi-аспекты , вы можете сделать это легко и компактно:

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

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

1 голос
/ 29 ноября 2018

Я создал функцию более высокого порядка, которая принимает код, который вы хотите измерить в / как лямбду:

class Utils {

    public static <T> T timeIt(String msg, Supplier<T> s) {
        long startTime = System.nanoTime();
        T t = s.get();
        long endTime = System.nanoTime();
        System.out.println(msg + ": " + (endTime - startTime) + " ns");
        return t;
    }

    public static void timeIt(String msg, Runnable r) {
       timeIt(msg, () -> {r.run(); return null; });
    }
}

Назовите это так:

Utils.timeIt("code 0", () ->
        System.out.println("Hallo")
);

// in case you need the result of the lambda
int i = Utils.timeIt("code 1", () ->
        5 * 5
);

Выход:

код 0: 180528 нс
код 1: 12003 нс

Отдельное спасибо Энди Тернеру , который помог мне сократить избыточность. См здесь .

1 голос
/ 20 ноября 2018

Вот несколько способов найти время выполнения в Java:

1) System.nanoTime ()

long startTime = System.nanoTime();
.....your code....
long endTime   = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println("Execution time in nanoseconds  : " + totalTime);
System.out.println("Execution time in milliseconds : " + totalTime / 1000000);

2) System.currentTimeMillis ()

long startTime = System.currentTimeMillis();
.....your code....
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds  : " + totalTime);

3) Instant.now ()

long startTime = Instant.now().toEpochMilli();
.....your code....
long endTime = Instant.now().toEpochMilli();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds: " + totalTime);

или

Instant start = Instant.now();
.....your code....
Instant end = Instant.now();
Duration interval = Duration.between(start, end);
System.out.println("Execution time in seconds: " +interval.getSeconds());

4) Date.getTime ()

long startTime = new Date().getTime();
.....your code....
long endTime = new Date().getTime();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds: " + totalTime);
1 голос
/ 04 апреля 2010

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

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

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

0 голосов
/ 29 декабря 2014

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

time java App

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...