Самый быстрый способ измерить прошедшее время в Java

Все, что я читал о currentTimeMillis и nanoTime, похоже, сосредоточено только на точности. Если я ищу только прошедшее время в миллисекундах, какой из них мне следует использовать, если мне нужна лучшая производительность?

Похоже, что currentTimeMillis был бы ответом, поскольку мне не нужно преобразовывать окончательный ответ из ns в ms, но это с точки зрения моего приложения, и то, что происходит под капотом, может сделать его неправильным выбором, поэтому я ' м спрашиваю.


person Brent212    schedule 25.10.2016    source источник
comment
Лично я просто использую #currentTimeMillis, вам редко когда нужна наносекундная точность, а неточности, которые могут возникнуть в обоих случаях, несущественны, если вы уже не работаете в этом масштабе (например, если вы проверяете в течение 10 секунд, погрешность 3-5 мс не убьет вас, хотя неточности, вероятно, гораздо меньше). хотя сравнения iirc #currentTimeMillis могут быть отрицательными, но опять же, очень маловероятно, если вы не работаете в этом масштабе (время, скажем, с 10-миллисекундными интервалами)   -  person Rogue    schedule 26.10.2016
comment
nanoTime так же точен (в худшем случае), как currentTimeMillis, если не лучше - с точки зрения точности. Что касается того, что быстрее, вам нужно быть немного более ясным для моего понимания.   -  person Nick Bell    schedule 26.10.2016
comment
NTP, пользователь, дополнительные секунды и другие источники изменяют значение currentTimeMillis напрямую, делая ваши измерения в некоторых случаях совершенно неверными. Если вы можете жить с этим, сделайте это. В противном случае используйте nanoTime, который является строго монотонным счетчиком и является причиной, по которой вам следует использовать nanoTime для любого серьезного приложения.   -  person zapl    schedule 26.10.2016


Ответы (2)


По сути, в чистой Java есть всего два варианта; вы уже назвали их:

  • System.currentTimeMillis
  • System.nanoTime

Оба метода являются встроенными в JVM.
В Linux они скомпилированы в прямые вызовы gettimeofday или clock_gettime соответственно.
В Windows - GetSystemTimeAsFileTime или QueryPerformanceCounter соответственно.

Производительность этих методов сильно зависит от платформы, архитектуры ЦП, версии ОС, версии Java, количества параллельных потоков и т. Д. на моем ноутбуке с Windows currentTimeMillis занимает 7 нс, а nanoTime - 16 нс, а на многопроцессорном сервере Linux оба метода занимают около 40 нс. Так что это зависит от обстоятельств.

Настоятельно рекомендую прочитать сообщение Алексея Шипилёва Нанотрастение нанотрему охватывает многие аспекты измерения времени в Java.

person apangin    schedule 25.10.2016
comment
Обновление: в Java 9 и новее мы можем вызвать _ 1_ с разрешением микросекунды. Обычные компьютерные аппаратные часы не могут более точно отслеживать время. - person Basil Bourque; 29.11.2019

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

person Mateo    schedule 25.10.2016