2017-05-15 3 views
3

Le module timeit est idéal pour mesurer le temps d'exécution de petits fragments de code, mais lorsque le code change d'état global (comme timeit), il est vraiment difficile d'obtenir des timings précis. Par exemple, si je veux chronométrer l'importation d'un module, la première importation prendra beaucoup plus de temps que les importations suivantes, car les sous-modules et les dépendances sont déjà importés et les fichiers sont déjà mis en cache. Donc, en utilisant une plus grande number de répétitions, comme dans:Synchronisation précise pour les importations en Python

>>> import timeit 
>>> timeit.timeit('import numpy', number=1) 
0.2819331711316805 

>>> # Start a new Python session: 
>>> timeit.timeit('import numpy', number=1000) 
0.3035142574359181 

ne fonctionne pas vraiment, parce que le temps pour une exécution est presque le même que pour 1000 tours. Je pouvais exécuter la commande « reload » le paquet:

>>> timeit.timeit('imp.reload(numpy)', 'import importlib as imp; import numpy', number=1000) 
3.6543283935557156 

Mais que c'est seulement 10 fois plus lent que le premier import semble indiquer qu'il est pas exact non plus. Il semble également impossible de décharger complètement un module ("Unload a module in Python"). Donc la question est: Quelle serait une façon appropriée de mesurer exactement le temps import?

+1

Bonne question. juste une idée, c'est peut-être mauvais: exécutez 100 fois l'interpréteur sur un script vide, puis 100 fois l'interpréteur avec 'import numpy' et soustrait. –

+3

Je pense que ça vaut la peine de demander pourquoi vous voulez faire ça ... Comme c'est un prix que vous ne paierez qu'une seule fois par programme, il est probablement suffisant de chronométrer l'importation une ou deux fois pour avoir un sens pour la lenteur qu'on éprouve ... les nombres durs ne signifient probablement pas autant ici parce que vous n'allez jamais assez lent pour que vos statistiques aient réellement un sens ... – mgilson

+0

@ Jean-FrançoisFabre Vous voulez dire créer un script qui appelle 'python -m timeit 'importe numpy' -r 1' depuis la ligne de commande? – MSeifert

Répondre

2

Comme il est presque impossible de décharger complètement un module, peut-être l'inspiration derrière cette réponse est this ...

Vous pouvez exécuter une boucle dans un script python pour exécuter x fois une commande python importation numpy et un autre ne rien faire, et soustraire les deux + moyenne:

import subprocess,time 

n=100 
python_load_time = 0 
numpy_load_time = 0 

for i in range(n): 
    s = time.time() 
    subprocess.call(["python","-c","import numpy"]) 
    numpy_load_time += time.time()-s 

    s = time.time() 
    subprocess.call(["python","-c","pass"]) 
    python_load_time += time.time()-s 

print("average numpy load time = {}".format((numpy_load_time-python_load_time)/n))