Точность System.nanoTime () для измерения прошедшего времени уменьшается после вызова Thread.sleep ()
Я столкнулся с действительно необычной проблемой здесь. Похоже, что вызов Thread.sleep (n), где n> 0, сделает следующие вызовы System.nanoTime () менее предсказуемыми.
Код ниже демонстрирует проблему.
Запуск его на моем компьютере (rMBP 15 "2015, OS X 10.11, jre 1.8.0_40-b26) дает следующий результат:
Control: 48497
Random: 36719
Thread.sleep(0): 48044
Thread.sleep(1): 832271
На виртуальной машине под управлением Windows 8 (VMware Horizon, Windows 8.1, 1.8.0_60-b27):
Control: 98974
Random: 61019
Thread.sleep(0): 115623
Thread.sleep(1): 282451
Однако, запустив его на корпоративном сервере (VMware, RHEL 6.7, jre 1.6.0_45-b06):
Control: 1385670
Random: 1202695
Thread.sleep(0): 1393994
Thread.sleep(1): 1413220
Что удивительно, результат, который я ожидаю.
Очевидно, что Thread.sleep (1) влияет на вычисление приведенного ниже кода. Я понятия не имею, почему это происходит. У кого-нибудь есть ключ?
Спасибо!
public class Main {
public static void main(String[] args) {
int N = 1000;
long timeElapsed = 0;
long startTime, endTime = 0;
for (int i = 0; i < N; i++) {
startTime = System.nanoTime();
//search runs here
endTime = System.nanoTime();
timeElapsed += endTime - startTime;
}
System.out.println("Control: " + timeElapsed);
timeElapsed = 0;
for (int i = 0; i < N; i++) {
startTime = System.nanoTime();
//search runs here
endTime = System.nanoTime();
timeElapsed += endTime - startTime;
for (int j = 0; j < N; j++) {
int k = (int) Math.pow(i, j);
}
}
System.out.println("Random: " + timeElapsed);
timeElapsed = 0;
for (int i = 0; i < N; i++) {
startTime = System.nanoTime();
//search runs here
endTime = System.nanoTime();
timeElapsed += endTime - startTime;
try {
Thread.sleep(0);
} catch (InterruptedException e) {
break;
}
}
System.out.println("Thread.sleep(0): " + timeElapsed);
timeElapsed = 0;
for (int i = 0; i < N; i++) {
startTime = System.nanoTime();
//search runs here
endTime = System.nanoTime();
timeElapsed += endTime - startTime;
try {
Thread.sleep(2);
} catch (InterruptedException e) {
break;
}
}
System.out.println("Thread.sleep(1): " + timeElapsed);
}
}
По сути, я выполняю поиск в цикле while, который прерывает каждую итерацию, вызывая Thread.sleep (). Я хочу исключить время ожидания из общего времени, затраченного на поиск, поэтому я использую System.nanoTime () для записи времени начала и окончания. Однако, как вы заметили выше, это не работает хорошо.
Есть ли способ исправить это?
Спасибо за любой вклад!