Je viens de rencontrer un comportement inattendu avec DateTime.UtcNow lors de certains tests unitaires. Il semble que lorsque vous appelez DateTime.Now/UtcNow en succession rapide, il semble vous rendre la même valeur pendant un intervalle de temps plus long que prévu, plutôt que de capturer des incréments de millisecondes plus précis.
Je sais qu'il existe une classe Stopwatch qui serait mieux adaptée pour effectuer des mesures de temps précises, mais j'étais curieux de savoir si quelqu'un pouvait expliquer ce comportement dans DateTime? Existe-t-il une précision officielle documentée pour DateTime.Now (par exemple, précise à moins de 50 ms?)? Pourquoi DateTime.Now serait-il moins précis que ce que la plupart des horloges CPU pourraient gérer? Peut-être qu'il est simplement conçu pour le processeur le plus petit dénominateur commun?
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();
}
Réponses:
Une bonne horloge doit être à la fois précise et précise ; ceux-ci sont différents. Comme le dit la vieille blague, une horloge arrêtée est exactement exacte deux fois par jour, une horloge lente d'une minute n'est jamais précise à aucun moment. Mais une horloge lente d'une minute est toujours précise à la minute près, alors qu'une horloge arrêtée n'a aucune précision utile.
Pourquoi le DateTime devrait-il être précis à, disons une microseconde alors qu'il ne peut pas être précis à la microseconde? La plupart des gens ne disposent d'aucune source pour les signaux horaires officiels précis à la microseconde. Par conséquent, donner six chiffres après la décimale de précision , dont les cinq derniers sont des ordures, serait mentir .
N'oubliez pas que le but de DateTime est de représenter une date et une heure . Les timings de haute précision ne sont pas du tout le but de DateTime; comme vous le remarquez, c'est le but de StopWatch. Le but de DateTime est de représenter une date et une heure à des fins telles que l'affichage de l'heure actuelle à l'utilisateur, le calcul du nombre de jours jusqu'à mardi prochain, et ainsi de suite.
Bref, "quelle heure est-il?" et "combien de temps cela a-t-il pris?" sont des questions complètement différentes; n'utilisez pas un outil conçu pour répondre à une question pour répondre à l'autre.
Merci pour la question; cela fera un bon article de blog! :-)
la source
La précision de DateTime est quelque peu spécifique au système sur lequel il est exécuté. La précision est liée à la vitesse d'un changement de contexte, qui tend à être d'environ 15 ou 16 ms. (Sur mon système, il s'agit en fait d'environ 14 ms de mes tests, mais j'ai vu certains ordinateurs portables où la précision est plus proche de 35-40 ms.)
Peter Bromberg a écrit un article sur la synchronisation de code de haute précision en C #, qui en traite.
la source
Je voudrais un Datetime.Now précis :), alors j'ai concocté ceci:
la source
À partir de MSDN, vous trouverez
DateTime.Now
une résolution approximative de 10 millisecondes sur tous les systèmes d'exploitation NT.La précision réelle dépend du matériel. Une meilleure précision peut être obtenue en utilisant
QueryPerformanceCounter
.la source
Pour ce que ça vaut, à moins de vérifier la source .NET, Eric Lippert a fourni un commentaire sur cette question SO en disant que DateTime n'est précise qu'à environ 30 ms. Le raisonnement pour ne pas être précis à la nanoseconde, selon ses mots, est que cela «n'a pas besoin de l'être».
la source
À partir de la documentation MSDN :
Ils affirment également que la résolution approximative sur Windows NT 3.5 et versions ultérieures est de 10 ms :)
la source
Par conséquent, les appels répétés à la propriété Now dans un court intervalle de temps, comme dans une boucle, peuvent renvoyer la même valeur.
Lien MSDN
la source