A precisão de System.nanoTime () para medir o tempo decorrido diminui após uma chamada para Thread.sleep ()
Estou encontrando um problema realmente incomum aqui. Parece que a chamada de Thread.sleep (n), em que n> 0, faria com que as seguintes chamadas System.nanoTime () fossem menos previsíveis.
O código abaixo demonstra o problema.
A execução no meu computador (rMBP 15 "2015, OS X 10.11, jre 1.8.0_40-b26) gera o seguinte resultado:
Control: 48497
Random: 36719
Thread.sleep(0): 48044
Thread.sleep(1): 832271
Em uma máquina virtual executando o Windows 8 (VMware Horizon, Windows 8.1, são 1.8.0_60-b27):
Control: 98974
Random: 61019
Thread.sleep(0): 115623
Thread.sleep(1): 282451
No entanto, executando-o em um servidor corporativo (VMware, RHEL 6.7, jre 1.6.0_45-b06):
Control: 1385670
Random: 1202695
Thread.sleep(0): 1393994
Thread.sleep(1): 1413220
O que é surpreendentemente o resultado que eu espero.
Claramente, o Thread.sleep (1) afeta o cálculo do código abaixo. Eu não tenho idéia do por que isso acontece. Alguém tem uma pista?
Obrigado!
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);
}
}
Basicamente, estou executando uma pesquisa em um loop while que interrompe cada iteração chamando Thread.sleep (). Quero excluir o tempo de suspensão do tempo total gasto para executar a pesquisa, por isso estou usando System.nanoTime () para registrar os horários de início e término. No entanto, como você notou acima, isso não funciona bem.
Existe uma maneira de remediar isso?
Obrigado por qualquer contribuição!