Измерение времени на Яве - PullRequest
3 голосов
/ 27 февраля 2012

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

i    alg1  alg2
4   0.002   0.0
5   0.001   0.0
6   0.003   0.002
7   0.023   0.01
8   0.055   0.041
9   0.056   0.0
10  0.208   0.101
11  1.767   0.694
12  18.581  7.784

, являющийся i просто некоторым входным параметром.

Я измерил производительность алгоритмов, используя следующую (наивную) функцию:

private double getDuration() {
    return (double)(System.currentTimeMillis() - startTime) / (double)1000;
}

Каким был бы предпочтительный способ получения более реальных результатов (кроме 0,0, что, очевидно, не 'правда!) чем использовать System.currentTimeMillis()?Я знаю, что мог бы просто запускать алгоритмы снова и снова и суммировать их результаты, но у меня есть ощущение, что, возможно, есть более надежный способ измерения прошедшего времени в Java (и real, user и sys, если возможно!).

Спасибо

Ответы [ 4 ]

6 голосов
/ 27 февраля 2012

Для базовой синхронизации вы можете использовать класс Stopwatch класса Guava (или просто захватить его исходный код, если вы не хотите загружать всю библиотеку Guava).Для более полного решения сравнительного анализа посмотрите на Штангенциркуль той же командой.

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

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

long timeA = System.currentTimeMillis();
doStuff();
long timeB = System.currentTimeMillis();
System.out.println("Elapsed time: " + (timeB - timeA));

, то можно получить отрицательный результат, если NTP отрегулирует в обратном направлении во время выполнения doStuff().System.nanoTime(), будучи таймером, а не часами, должен игнорировать эту настройку, таким образом, избегая этой проблемы.

(Обратите внимание, что все вышеперечисленное является концептуальным; к сожалению, на уровне реализации все может запутаться. Но это неНе меняйте рекомендацию: System.nanoTime() должен быть лучшим таймером, который вы можете получить на своей платформе, а System.currentMilliseconds() должен быть лучшим, который вы можете получить.)

2 голосов
/ 27 февраля 2012

Вам следует рассмотреть возможность многократного запуска ваших алгоритмов и усреднения результата.

Для этого есть три причины:

  1. Это упрощает синхронизацию по тем причинам, по которым выопределили.

  2. JVM "нагревается", и производительность вашего кода будет меняться, как это происходит: JVM горячей точки не будет компилироваться полностью, пока вы не запустите большой методколичество раз.Если вы не пройдете мимо этого, ваши результаты не будут репрезентативными.

  3. Это всегда хорошая идея, чтобы усреднить время, чтобы избежать побочных эффектов из-за внешних событий, таких как GC,или другие вещи, работающие на вашем компьютере.

Как правило, попробуйте запустить ваши алгоритмы 10000 раз в качестве разминки, а затем 10000 раз после этого.Измените числа, чтобы они соответствовали вашим временам выполнения ...

Вот статья , объясняющая то же самое.

2 голосов
/ 27 февраля 2012

System.nanoTime(); возможно, это то, что вы ищете.И добавьте вычисления для стандартного отклонения и среднего времени.

1 голос
/ 12 июля 2014

Вы можете обработать код и посчитать количество выполненных байт-кодов. Вы можете сделать это с помощью bycounter .

Это не может быть идеальным для ваших целей. Если программы отличаются только на несколько байт-кодов, это может не дать точной оценки того, какая программа на самом деле более производительна, так как стоимость выполнения байт-кодов может сильно отличаться. Кроме того, если во время вашей программы происходит чтение по сети или с диска, счетчик байт-кода может дать неправильное сравнение.

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