Как я могу измерить время с точностью до микросекунды в Java? - PullRequest
21 голосов
/ 02 февраля 2009

В Интернете я увидел, что должен был использовать System.nanoTime(), но это не работает для меня - оно дает мне время с точностью до миллисекунд. Мне просто нужны микросекунды до и после выполнения моей функции, чтобы я знал, сколько времени это займет. Я использую Windows XP.

По сути, у меня есть этот код, который, например, выполняет от 1 до 10 миллионов вставок в связанный список Java. Проблема в том, что я не могу измерить правильную точность; иногда для вставки всего в меньший список требуется меньше времени.

Вот пример:

class test
{
    public static void main(String args[])
    {
        for(int k=1000000; k<=10000000; k+=1000000)
        {
            System.out.println(k);
            LinkedList<Integer> aux = new LinkedList<Integer>();
            //need something here to see the start time
            for(int i=0; i<k; i++)
                aux.addFirst(10000);
            //need something here to see the end time
            //print here the difference between both times
        }
    }
}

Я делал это много раз - внешний цикл делал это 20 раз для каждого k - но результат не очень хороший. Иногда для создания 10 миллионов вставок требуется меньше времени, чем для 1 миллиона, поскольку я не получаю правильное измеренное время с тем, что я использую сейчас (System.nanoTime ())

Редактировать 2: Да, я использую Sun JVM.

Редактировать 3: Возможно, я сделал что-то не так в коде, посмотрю, будет ли изменение делать то, что я хочу.

Редактировать 4: Моя ошибка, кажется, System.nanoTime () работает. Уф.

Ответы [ 12 ]

0 голосов
/ 14 октября 2015

«быстрое и грязное» решение, с которым я в конце концов пошел:

TimeUnit.NANOSECONDS.toMicros(System.nanoTime());

UPDATE:

Первоначально я использовал System.nanoTime, но потом обнаружил, что его следует использовать только в течение истекшего времени, в конце концов я изменил свой код для работы с миллисекундами или в некоторых местах:

TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());

но это просто добавит нули в конце значения (micros = millis * 1000)

Оставьте этот ответ здесь как "предупреждающий знак" на случай, если кто-то еще подумает о nanoTime:)

0 голосов
/ 02 февраля 2009

Такой тест, основанный на коротком временном интервале, дает вам ненадежные результаты. Вы всегда будете получать разные результаты из-за внешних факторов, таких как ввод-вывод, перестановка, переключение процессов, кэши, сборка мусора и т. Д. Кроме того, JVM оптимизирует ваши вызовы, поэтому вероятно, что первые измеренные события будут выполняться медленнее, чем последующие вызовы. JVM начинает все больше и больше оптимизировать выполняемые вами команды.

Кроме того, метод, подобный System.nanoTime (), зависит от таймеров базовой системы. Они могут (и, скорее всего, будут) не иметь гранулярности для измерения с такой точностью. Чтобы процитировать API :

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

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

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

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