Высокоточный секундомер Java - PullRequest
4 голосов
/ 25 февраля 2011

У меня есть эта проблема, и я не могу понять, как ее решить.
Мне нужно измерить время, необходимое для выполнения определенной функции.Хорошо, функция секундомера, которая измеряет время в миллисекундах, была недостаточно хороша, поэтому я использовал измерение в наносекундах.

Проблема в том, что функция заканчивается так быстро, что даже секундомер за нано секунды не может ее измерить.

Я знаю, что секундомер работает, потому что я пытался вставить, например, Thread.sleep(1) в свою функцию (Thread.sleep в миллисекундах), и я получаю свое время, но без Thread.sleep мое время всегда0. Есть идеи?

Вот мой код:

long startTimeLocalNS=0;
long stopTimeLocalNS = 0;
startTimeLocalNS = System.nanoTime();
if (something)
{
    /*my Code;*/
}   
stopTimeLocalNS = System.nanoTime();
disconnectTime = (stopTimeLocalNS - startTimeLocalNS);

Ответы [ 7 ]

7 голосов
/ 25 февраля 2011

Как насчет запуска функции несколько тысяч (или миллионов) раз в цикле, измерения общего времени и деления его на количество итераций?

Но остерегайтесь многих ошибок при написании микробенчмарков .

1 голос
/ 25 февраля 2011

Профилируете ли вы какой-нибудь код?Если это так, профили, доступные на рынке, будут работать намного лучше.

Если вам просто нужно измерить очень короткий промежуток времени, у вас есть несколько вариантов:

  • System.currentTimeMillis()- на моем компьютере он имеет разрешение 60 Гц, что дает гранулярность около 16 мс
  • System.nanoTime() - предположим, что это более точно, но я слышал, что в эпоху многоядерных процессоров это не самое быстрое решение
  • JNI - измерьте время в C, но стоимость вызова JNI будет значительной.
1 голос
/ 25 февраля 2011

Вы можете циклически пройти код, подлежащий измерению, 1000 раз, а затем разделить разницу nanoTime на 1000.

1 голос
/ 25 февраля 2011

Вы можете сделать что-то вроде этого:

long startTimeLocalNS=0;
long stopTimeLocalNS = 0;
int count = 10000;
startTimeLocalNS = System.nanoTime();
if (something)
{
    while(count-- != 0) {
    /*my Code;*/
    }
}   
stopTimeLocalNS = System.nanoTime();
disconnectTime = (stopTimeLocalNS - startTimeLocalNS) / count;
0 голосов
/ 25 февраля 2011

Ответ из левого поля: как утверждает Питер Лори, большинство систем должны возвращать число больше нуля для результата при сравнении двух вызовов с nanoTime(). Тем не менее, вы абсолютно уверены, что вы сравниваете правильные значения? Не могли бы вы случайно сделать это:

long startTime = System.nanoTime();
if (something)
{
    /*my Code;*/
}
long stopTime = System.nanoTime();
disconnectTime = stopTime - stopTime; //note the error - you are subtracting stoptime from itself

Итак, мой вопрос: есть ли в вашем коде ошибка, которую вы не воспроизвели в приведенном выше примере кода?

Второй вопрос, вы уверены, что something==true?

0 голосов
/ 25 февраля 2011

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

0 голосов
/ 25 февраля 2011

Если вы хотите сравнить свою функцию, проще всего запустить ее несколько раз за одно измерение.Затем разделите время на количество звонков.

...