Pular para o conteúdo

Voltar para o blog

Curiosidade

Por que 1ms nem sempre significa 1ms

· 6 min

Um milissegundo parece uma unidade precisa e inequívoca, mas a precisão real de um timestamp lido em código depende da fonte de relógio por trás dele, que varia mais do que a maioria assume.

Ilustração de um relógio com ponteiro tracejado

Resolução não é o mesmo que precisão

Um relógio pode reportar valores formatados em milissegundos (como `Date.now()`) enquanto o timer do sistema operacional por trás só é atualizado a cada poucos milissegundos de fato, várias leituras consecutivas podem retornar o mesmo valor mesmo com tempo real passando entre elas, escondendo diferenças menores que esse intervalo de atualização.

Contadores monotônicos existem por um motivo específico

O relógio de parede pode voltar no tempo, sincronização NTP, segundos bissextos, ajuste manual, então medir duração com timestamps de relógio de parede pode gerar durações negativas ou completamente erradas. Relógios monotônicos (`performance.now()`, `System.nanoTime()`, `CLOCK_MONOTONIC`) existem especificamente pra nunca voltar no tempo, por isso são a ferramenta certa pra medir duração, nunca pra registrar quando algo aconteceu.

Jitter: por que duas medições do mesmo código dão números diferentes

Escalonamento de frequência da CPU, outros processos disputando o mesmo núcleo, efeitos de cache, pausas de garbage collector em runtimes gerenciados, tudo isso introduz ruído na medição. Uma única medição de uma operação rápida é quase sem sentido isolada; o que importa é a distribuição ao longo de muitas execuções.

A consequência prática

Quando a duração medida chega perto da resolução real do relógio, uma query de ~1ms num relógio que atualiza a cada ~15ms, por exemplo, não vale confiar no número isolado. O caminho certo é medir muitas iterações e olhar pra distribuição, ou trocar pra uma fonte monotônica de alta resolução, feita exatamente pra esse tipo de medição.