Me encontré con un comportamiento inesperado con DateTime.UtcNow mientras hacía algunas pruebas unitarias. Parece que cuando llama a DateTime.Now/UtcNow en rápida sucesión, parece devolverle el mismo valor durante un intervalo de tiempo más largo de lo esperado, en lugar de capturar incrementos de milisegundos más precisos.
Sé que hay una clase de cronómetro que sería más adecuada para realizar mediciones de tiempo precisas, pero tenía curiosidad por saber si alguien podría explicar este comportamiento en DateTime. ¿Existe una precisión oficial documentada para DateTime.Now (por ejemplo, con una precisión de 50 ms?)? ¿Por qué DateTime.Now sería menos preciso de lo que podrían manejar la mayoría de los relojes de CPU? ¿Quizás solo está diseñado para la CPU con el mínimo común denominador?
public static void Main(string[] args)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i=0; i<1000; i++)
{
var now = DateTime.Now;
Console.WriteLine(string.Format(
"Ticks: {0}\tMilliseconds: {1}", now.Ticks, now.Millisecond));
}
stopwatch.Stop();
Console.WriteLine("Stopwatch.ElapsedMilliseconds: {0}",
stopwatch.ElapsedMilliseconds);
Console.ReadLine();
}
Respuestas:
Un buen reloj debe ser preciso y exacto ; esos son diferentes. Como dice el viejo chiste, un reloj parado es exactamente exacto dos veces al día, un reloj un minuto lento nunca es exacto en ningún momento. Pero el reloj un minuto lento siempre es preciso al minuto más cercano, mientras que un reloj parado no tiene ninguna precisión útil.
¿Por qué la fecha y hora debería ser precisa , digamos un microsegundo, cuando no es posible que tenga una precisión del microsegundo? La mayoría de la gente no tiene ninguna fuente de señales horarias oficiales con una precisión de microsegundos. Por lo tanto, dar seis dígitos después del lugar decimal de precisión , los últimos cinco de los cuales son basura sería mentir .
Recuerde, el propósito de DateTime es representar una fecha y una hora . Los tiempos de alta precisión no son en absoluto el propósito de DateTime; como nota, ese es el propósito de StopWatch. El propósito de DateTime es representar una fecha y hora para propósitos como mostrar la hora actual al usuario, calcular el número de días hasta el próximo martes, y así sucesivamente.
En resumen, "¿qué hora es?" y "¿cuánto tiempo te llevó?" son preguntas completamente diferentes; no use una herramienta diseñada para responder una pregunta para responder a la otra.
Gracias por la pregunta; ¡Esto será un buen artículo de blog! :-)
fuente
La precisión de DateTime es algo específica del sistema en el que se ejecuta. La precisión está relacionada con la velocidad de un cambio de contexto, que suele rondar los 15 o 16 ms. (En mi sistema, en realidad está a unos 14 ms de mi prueba, pero he visto algunas computadoras portátiles en las que está más cerca de una precisión de 35-40 ms).
Peter Bromberg escribió un artículo sobre sincronización de código de alta precisión en C #, que analiza esto.
fuente
Me gustaría una fecha y hora precisa. Ahora :), así que preparé esto:
fuente
De MSDN encontrará que
DateTime.Now
tiene una resolución aproximada de 10 milisegundos en todos los sistemas operativos NT.La precisión real depende del hardware. Se puede obtener una mejor precisión utilizando
QueryPerformanceCounter
.fuente
Por lo que vale, aparte de verificar realmente la fuente .NET, Eric Lippert proporcionó un comentario sobre esta pregunta SO diciendo que DateTime solo tiene una precisión de aproximadamente 30 ms. El razonamiento para no ser preciso en nanosegundos, en sus palabras, es que "no tiene por qué serlo".
fuente
De la documentación de MSDN :
También afirman que la resolución aproximada en Windows NT 3.5 y posterior es de 10 ms :)
fuente
Como resultado, las llamadas repetidas a la propiedad Now en un intervalo de tiempo corto, como en un bucle, pueden devolver el mismo valor.
Enlace MSDN
fuente