Mesure du temps écoulé En python
Existe-t-il un moyen simple / module pour correctement mesurer le temps écoulé en python? Je sais que je peux simplement appeler time.time()
deux fois et prendre la différence, mais cela donnera de mauvais résultats si le temps du système est modifié. C'est vrai, ça n'arrive pas souvent, mais ça indique que je mesure la mauvaise chose.
utiliser time.time()
pour mesurer les durées est incroyablement rond-point quand on y pense. Vous prenez la différence entre deux mesures de temps absolu qui sont à leur tour construites à partir de mesures de durée (effectuées par des minuteries) et des temps absolus connus (définis manuellement ou via ntp), qui ne vous intéressent pas du tout.
Alors, est-il un moyen d'interroger ce "timer temps" directement? J'imagine qu'il peut être représenté comme une valeur de milliseconde ou de microseconde qui n'a pas de représentation absolue significative (et donc n'a pas besoin d'être ajustée avec le temps du système). En cherchant un peu il semble que c'est exactement ce que System.nanoTime()
fait en Java, mais je n'ai pas trouvé de fonction Python correspondante, même si elle devrait (matériel-techniquement) être plus facile à fournir que time.time()
.
Modifier: pour éviter la confusion et répondre aux réponses ci - dessous: il ne s'agit pas de changements D'heure, et je ne veux pas non plus de temps CPU-je veux temps physique écoulé. Il n'a pas besoin d'être très fin, et même pas particulièrement précis. Il ne devrait pas me donner négative les durées, ou les durées qui sont désactivées de plusieurs ordres de grandeur (au-dessus de la granularité), juste parce que quelqu'un a décidé de mettre l'horloge du système à une valeur différente. Voici ce que les docteurs Python disent à propos de l'heure.time ()':
"alors que cette fonction renvoie normalement des valeurs non décroissantes, elle peut renvoyer une valeur inférieure à un appel précédent si l'horloge du système a été retardée entre les deux appels"
C'est exactement ce que je voulez éviter, car elle peut conduire à des choses étranges comme des valeurs négatives dans les calculs de temps. Je peux y remédier pour le moment, mais je pense que c'est une bonne idée d'apprendre à utiliser les bonnes solutions lorsque c'est possible, puisque les kludges reviendront vous mordre un jour.
Edit2: certaines recherches montrent que vous pouvez obtenir une mesure indépendante du temps système comme je veux dans Windows en utilisant GetTickCount64(), sous Linux vous pouvez l'obtenir dans la valeur de retour de times(). Cependant, Je Je ne trouve toujours pas de module qui fournit cette fonctionnalité en Python.
6 réponses
ce que vous semblez chercher est un minuteur monotone . Un référence de temps monotone ne saute pas ou ne recule pas.
il y a eu plusieurs tentatives pour implémenter une horloge monotomique pour Python basée sur la référence OS de celle-ci. (Windows, POSIX et BSD sont tout à fait différents) voir les discussions et certaines des tentatives de temps monotone dans ce SO post .
la plupart du temps, vous pouvez utiliser os.fois():
os.times()
retourner un 5-tuple de nombres à virgule flottante indiquant temps accumulé (processeur ou autre), en secondes. Les éléments sont: temps de l'Utilisateur, Temps du système, temps de l'Utilisateur des Enfants, Temps du système des enfants, et le temps réel écoulé depuis un point fixe dans le passé, dans cet ordre. Voir la page de manuel Unix times (2) ou les fenêtres correspondantes Documentation de l'API de plate-forme. Sur les fenêtres, seuls les deux premiers éléments sont remplis, les autres sont nuls.
Disponibilité: Unix, Windows
mais cela ne remplit pas le temps réel nécessaire (le cinquième tuple) sur Windows.
si vous avez besoin du soutien de Windows, considérez ctypes
et vous pouvez appeler GetTickCount64() directement, comme cela a été fait dans cette recette .
pour mesurer le temps CPU écoulé, regardez .horloge() . C'est l'équivalent du champ Temps utilisateur times() de Linux.
Pour l'analyse comparative, l'utilisation timeit .
le module datetime , qui fait partie de Python 2.3+ , a également le temps de microseconde si pris en charge par la plate-forme.
exemple:
>>> import datetime as dt
>>> n1=dt.datetime.now()
>>> n2=dt.datetime.now()
>>> (n2-n1).microseconds
678521
>>> (n2.microsecond-n1.microsecond)/1e6
0.678521
ie, it took me .678521 seconds to type the second n2= line -- slow
>>> n1.resolution
datetime.timedelta(0, 0, 1)
1/1e6 resolution is claimed.
si vous êtes préoccupé par les changements de temps système (à partir de DS -> ST), il suffit de vérifier l'objet retourné par datetime.On peut supposer que le temps du système pourrait avoir un petit ajustement à partir d'un ajustement de référence NTP . cela doit être modifié , et les corrections sont appliqué graduellement , mais NTP Sync beats peut avoir un effet avec de très petites références de temps (millisec ou microsec).
Vous pouvez également référence Alex Martelli C de la fonction si vous voulez quelque chose de cette résolution. Je n'irais pas trop loin pour réinventer la roue. Le temps exact est basique et la plupart des OS modernes font un assez bon travail.
Modifier
basé sur vos clarifications, il semble que vous avez besoin d'une simple vérification latérale si l'horloge du système a changé. Il suffit de comparer à un serveur ntp amical et local:
import socket
import struct
import time
ntp="pool.ntp.org" # or whatever ntp server you have handy
client = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
data = '\x1b' + 47 * '"151910920"'
client.sendto( data, ( ntp, 123 ))
data, address = client.recvfrom( 1024 )
if data:
print 'Response received from:', address
t = struct.unpack( '!12I', data )[10]
t -= 2208988800L #seconds since Epoch
print '\tTime=%s' % time.ctime(t)
NTP est précis à des millisecondes sur Internet et a une résolution de représentation de résolution de 2-32 secondes (233 picosecondes). Devrait être assez bon?
soyez conscient que la structure de données NTP 64 bits débordera en 2036 et tous les 136 ans par la suite -- si vous voulez vraiment une solution robuste, mieux vérifier le débordement...
Python 3.3 a ajouté un minuterie monotonique dans la bibliothèque standard, ce qui fait exactement ce que je cherchais. Merci à Paddy3118 d'avoir souligné ceci dans " Comment puis-je obtenir des durées de temps monotones en python?" .
>>> import datetime
>>> t1=datetime.datetime.utcnow()
>>> t2=datetime.datetime.utcnow()
>>> t2-t1
datetime.timedelta(0, 8, 600000)
utilisant UTC évite ces périodes embarrassantes lorsque l'horloge change en raison de l'heure d'été.
quant à l'utilisation d'une méthode alternative plutôt que de soustraire deux horloges, sachez que L'OS contient effectivement une horloge qui est initialisée à partir d'une horloge matérielle dans le PC. Les implémentations modernes de systèmes D'exploitation maintiendront également cette horloge synchronisée avec une source officielle pour qu'elle ne dérive pas. C'est beaucoup plus précis que n'importe quel chronomètre le PC peut-être en cours d'exécution.
les fonctions d'exemple que vous déclarez dans votre édition sont deux choses complètement différentes:
- Linux times () renvoie les temps de traitement en CPU millisecondes. L'équivalent de Python est le temps.horloge() ou
os.times()
. - Windows GetTickCount64() renvoie à la disponibilité du système.
bien que deux fonctions différentes, les deux (potentiellement) pourraient être utilisées pour révéler une horloge système qui avait un "rot" avec ces méthodes:
premier:
vous pouvez prendre à la fois un temps système avec time.time()
et un temps CPU avec time.clock()
. Étant donné que l'Heure de l'horloge murale sera toujours supérieure ou égale à L'heure CPU, éliminer toute mesure où l'intervalle entre les deux lectures time.time()
est inférieur aux lectures de contrôle time.clock()
appariées.
exemple:
t1=time.time()
t1check=time.clock()
# your timed event...
t2=time.time()
t2check=time.clock()
if t2-t1 < t2check - t1check:
print "Things are rotten in Denmark"
# discard that sample
else:
# do what you do with t2 - t1...
la Deuxième:
obtenir le temps de fonctionnement du système est également prometteur si vous êtes préoccupé par l'horloge du système, car un utilisateur reset ne réinitialise pas le nombre de temps de fonctionnement dans la plupart des cas. (que je suis au courant...)
maintenant la question plus difficile: obtenir le système temps de fonctionnement d'une manière indépendante de plate-forme-en particulier sans frayer une nouvelle coquille-à la précision de la sous-seconde. Hmmm...
probablement le le meilleur pari est psutil . parcourant la source , ils utilisent uptime = GetTickCount() / 1000.00f;
Pour Windows et sysctl "kern.boottime"
pour BSD / OS X, etc. Malheureusement, il s'agit d'une résolution d'une seconde.
from datetime import datetime
start = datetime.now()
print 'hello'
end = datetime.now()
delta = end-start
print type(delta)
<type 'datetime.timedelta'>
import datetime
help(datetime.timedelta)
...elapsed seconds and microseconds...