Почему это система.nanoTime() путь более медленный (в представлении) чем система.currentTimeMillis()?
сегодня я сделал небольшой быстрый тест, чтобы проверить скорость работы System.nanoTime() и System.currentTimeMillis():
long startTime = System.nanoTime();
for(int i = 0; i < 1000000; i++) {
long test = System.nanoTime();
}
long endTime = System.nanoTime();
System.out.println("Total time: "+(endTime-startTime));
вот результаты:
System.currentTimeMillis(): average of 12.7836022 / function call
System.nanoTime(): average of 34.6395674 / function call
почему различия в скорости бега так велики?
тест система:
Java 1.7.0_25
Windows 8 64-bit
CPU: AMD FX-6100
5 ответов:
System.currentTimeMillis()реализуется с помощью GetSystemTimeAsFileTime метод, который по существу просто читает низкий разрешение значение времени суток, которое поддерживает Windows. Читающий эту глобальная переменная естественно очень быстра-около 6 циклов согласно отчетная информация.
System.nanoTime()реализуется с помощьюQueryPerformanceCounter/ QueryPerformanceFrequency API(Если имеется, иначе он возвращаетcurrentTimeMillis*10^6).QueryPerformanceCounter(QPC)реализуется в разных пути в зависимости от оборудования, на котором он работает. Как правило, он будет использовать либо программируемый интервал-таймер (ПИТ), или быстрого питания таймер управления (PMT) или счетчик времени на уровне ЦП (TSC). Доступ к PIT / PMT требует выполнения медленных инструкций порта ввода-вывода и в результате время выполнения для QPC находится в порядке микросекунды. В отличие от чтения TSC находится на порядка 100 часов циклы (для считывания TSC с чипа и преобразования его в значение времени на основе рабочая частота.)возможно, это ответ на вопрос. Эти два метода используют различное количество тактов, что приводит к низкой скорости более позднего.
далее в этом блоге в разделе заключение:
если вы заинтересованы в измерении / вычислении затраченного времени, то всегда используйте систему.nanoTime(). На большинстве систем это даст разрешение порядка микросекунд. Помните, однако этот вызов также может принять микросекунды для выполнения на некоторых платформах.
большинство ОС (вы не упомянули, какой из них вы используете) имеют счетчик/часы в памяти, который обеспечивает точность миллисекунды (или близко к этому). Для получения наносекундной точности большинству приходится считывать аппаратный счетчик. Связь с оборудованием происходит медленнее, чем чтение некоторого значения уже в памяти.
это может быть только в Windows. Смотрите ответ на подобный вопрос.
по сути,
System.currentTimeMillis()просто читает глобальную переменную, поддерживаемую Windows (которая имеет низкую степень детализации), тогда какSystem.nanoTime()на самом деле должен выполнять операции ввода-вывода.
вы измеряете это на Windows, не так ли. Я прошел это упражнение в 2008 году. nanoTime медленнее на Windows, чем currentTimeMillis. Насколько я помню, в Linux nanotime быстрее, чем currentTimeMillis, и, конечно же, быстрее, чем в Windows.
важно отметить, что если вы пытаетесь измерить совокупность нескольких субмиллисекундных операций, вы должны использовать nanotime, как если бы операция закончилась менее чем за 1/1000 секунды вашего кода, сравнивая currentTimeMillis покажет операцию как мгновенную, поэтому 1000 из них все равно будут мгновенными. Возможно, вы захотите использовать nanotime, а затем округлить до ближайшей миллисекунды, поэтому, если операция заняла 8000 наносекунд, она будет считаться 1 миллисекундой, а не 0.
возможно, вы захотите использовать nanotime, а затем округлить до ближайшей миллисекунды, поэтому, если операция заняла 8000 наносекунд, она будет считаться 1 миллисекундой, а не 0.
арифметические Примечание:
8000 наносекунд составляет 8 микросекунд составляет 0,008 миллисекунд. Округление будет считать, что в 0 миллисекунд.
Comments