Je trouve que le système.diagnostics.stopwatch Classe a ce qui semble être une inexactitude mesurable, même sur une courte période (c'est-à-dire 20 secondes). Mon processus montre une heure écoulée de 20,3 secondes pour un processus codé pour exécuter 20 secondes:
$elapsed = [System.Diagnostics.Stopwatch]::StartNew() write-host "Started at $(get-date)" for ($t=1; $t -le 20; $t++) { Write-Host "Elapsed Time: $($elapsed.Elapsed.ToString())" sleep 1 } write-host "Ended at $(get-date)" write-host "Total Elapsed Time: $($elapsed.Elapsed.ToString())" Started at 02/02/2013 15:08:43 Elapsed Time: 00:00:00.0329924 Elapsed Time: 00:00:01.0417435 Elapsed Time: 00:00:02.0547547 Elapsed Time: 00:00:03.0689716 Elapsed Time: 00:00:04.0820497 Elapsed Time: 00:00:05.0963413 Elapsed Time: 00:00:06.1113915 Elapsed Time: 00:00:07.1244044 Elapsed Time: 00:00:08.1396105 Elapsed Time: 00:00:09.1528952 Elapsed Time: 00:00:10.1659905 Elapsed Time: 00:00:11.1800884 Elapsed Time: 00:00:12.1940009 Elapsed Time: 00:00:13.2081824 Elapsed Time: 00:00:14.2223585 Elapsed Time: 00:00:15.2375023 Elapsed Time: 00:00:16.2506360 Elapsed Time: 00:00:17.2656845 Elapsed Time: 00:00:18.2790676 Elapsed Time: 00:00:19.2928700 Ended at 02/02/2013 15:09:04 Total Elapsed Time: 00:00:20.3080067
4 Réponses :
Vous avez 20 pauses de 1 seconde, mais vous avez d'autres choses qui se passent aussi. Il existe une boucle qui augmente et teste une variable et vous écrivez le temps écoulé sur chaque itération. Ces choses supplémentaires prennent du temps.
Cela a toujours une pause de 20 secondes, et le temps écoulé est plus proche de 20 secondes car il y a moins de choses supplémentaires que PowerShell doit faire: P>
$elapsed = [System.Diagnostics.Stopwatch]::StartNew() write-host "Started at $(get-date)" sleep 20 write-host "Ended at $(get-date)" write-host "Total Elapsed Time: $($elapsed.Elapsed.ToString())"
Débarrassez-vous des appels d'hôte écriture démarrés et terminés et cela devrait être encore plus proche. Chronomètre utilise l'API de compteur haute fréquence de Windows 'afin qu'il soit assez précis.
Rynant, ce serait 20 secondes. Mais ce ne serait plus un chronomètre - juste une minuterie de sommeil. Cela empêcherait mon script de courir jusqu'à ce que le sommeil soit terminé. J'en ai besoin pour courir un processus et à la fin, dites-moi combien de temps il a fallu pour compléter.
Je pense que vous avez manqué le point de mon exemple. J'essayais de montrer que la classe diagnostics.stopwatch code> n'est pas inexacte. La raison pour laquelle le chronomètre de votre script affiche "20.3080067" Seconds est parce que votre script fait d'autres choses en plus de dormir. En outre, la raison pour laquelle les instructions
get-date code> semblent être exactement à 20 secondes d'être car l'heure affichée est arrondie à la seconde la plus proche.
Je t'ai eu. Donc, si vous exécutez mes commandes supplémentaires lève les chronomètres, comment utiliser une chronomètre pour effectivement un processus avec précision? Ou chronométrant ne serait-il pas la voie à suivre pour quelque chose comme ça? Mon code actuel pourrait prendre des heures à compléter et je voudrais obtenir un temps écoulé plus précis que cela.
Exécuter des commandes supplémentaires ne jette pas les chronomètres. Exécuter des commandes supplémentaires prend plus de temps; Par conséquent, chronomètre montre la bonne heure. Utilisez chronomètre, il est précis.
La question est, qu'essayez-vous de faire? Si vous essayez de déterminer combien de temps il faut un script à exécuter, vous devez utiliser exactement le chronomètre. Toutefois, si vous essayez de démarrer une nouvelle séquence de commandes après une période spécifiée, utilisez un [System.Timers.Timer] et enregistrez un événement pour l'événement écoulé sur l'objet TIMER. Spécifiez ensuite l'action de l'événement enregistré à ce que vous essayez d'accomplir. P>
Le temps total de votre code est exécuté, dépend d'autres facteurs, tels que la fréquentation de votre système.
En regardant le code source de .NET, nous pouvons voir que [System.Diagnostics.stopwatch] :: StartNew () Utilise le temps haute résolution compteur. Il appelle le Winapi QueryPerformEcanceCounter < / a>. C'est-à-dire que la classe est si précise! P> Je regarde Code source le plus récent de Start-Sleep et a noté qu'il utilise des événements en mode noyau pour mettre en œuvre le temps d'attente. En plus des détails déjà mentionnés par les utilisateurs, la planification de Windows peut mettre un autre thread à exécuter lorsque PowerShel termine votre attente pour le temps de veille, ce qui a entraîné plus de temps avant que votre code ne calcule le temps écoulé. P> aussi, écrivant à la La vidéo est une opération de coût car il s'agit d'une ressource très haute utilisée sur ordinateur. Pour réussir, je réécris votre code, de sorte que cela n'écrit pas à la vidéo à chaque fois: p> Jetez un coup d'oeil sur les exécutions sur système, PowerShell 5.1, bureau, Windows 10, CPU Intel 3.0 GHz. P> Premier, j'ai couru votre code d'origine, à la priorité normale, faible simultanéité: script a pris 20.14s p> Suivant, j'ai dirigé le code d'origine, avec un autre processus intensif de la CPU: a pris 24,21s p> retour, j'ai exécuté ma version de code, sans l'hôte en écriture sous système de veille:
Le dernier a une grande différence pour la première ( oisif avec écrit à l'écran). P> p>
chronomètre est très précis. Le sommeil n'est pas. Dormir pendant 1 seconde donnera typiquement n'importe où de 0,985 à un sommeil 1.015S; Cependant, cela pourrait être sensiblement plus long s'il existe d'autres activités. P>