Desidero sapere quanto tempo richiede un'importazione sia per i moduli predefiniti sia per quelli definiti dall'utente.Tempo impiegato da un'importazione in Python
risposta
È possibile verificare questo runnning
$ time python -c "import math"
Tuttavia, che cosa sarebbe questo aiuto? L'importazione avviene solo una volta e non sarà quasi mai un collo di bottiglia. L'importazione dello stesso modulo più e più volte non verrà eseguita molto più lentamente dell'importazione una volta, poiché Python tiene traccia di quali moduli sono già stati importati.
Cosa stai cercando di ottenere?
Ho uno script master che importa altri moduli. Devo calcolare quanto tempo ci vuole – user46646
@rejinacm: Si prega di aggiornare la domanda con nuovi fatti. –
Uso profiler: http://docs.python.org/library/profile.html
In ogni caso, le importazioni vengono memorizzati nella cache.
testato su Windows in Python 2.4 - si può provare da soli.
>>> import time
>>> ## Built-in module
>>> def testTime():
now = time.clock() # use time.time() on unix-based systems
import math
print time.clock() - now
>>> testTime()
7.54285810167e-006
>>> ## My own module
>>> def testTime():
now = time.clock()
import myBuiltInModule # Not its actual name ;-)
print time.clock() - now
>>> testTime()
0.00253174635324
>>> testTime()
3.70158777141e-006
Quindi c'è una grande differenza tra i moduli memorizzati nella cache e quelli introdotti da zero. Per illustrare, siamo in grado di ricaricare il modulo:
>>> def testTime():
now = time.clock()
reload(myBuiltInModule)
print time.clock() - now
>>> testTime()
0.00250017809526
per scoprire quanto tempo un'importazione prende, il modo più semplice probabilmente sta usando il timeit module ..
>>> import timeit
>>> t = timeit.Timer('import urllib')
>>> t.timeit(number = 1000000)
0.98621106147766113
Quindi, per importare urllib 1 milione di volte, ci sono voluti poco meno di un secondo (su un MacBook Pro) ..
Ho uno script master che importa altro modules.I bisogno di calcolare quanto tempo ci vuole
Se si intende il tempo totale di esecuzione dello script, su Linux/OS X/Cygwin, è possibile eseguire lo script utilizzando il comando time
, ad esempio:
$ time python myscript.py
real 0m0.046s
user 0m0.024s
sys 0m0.020s
(ricordate che comprende tutta l'interprete Python tempo di avvio, così come i tempi di esecuzione codice vero e proprio, anche se è piuttosto banale quantità)
Un altro modo forse più utile è al profilo lo script:
Invece di eseguire il codice con
$ python myscript.py
..si utilizza ..
$ python -m cProfile myscript.py
1059 function calls in 0.015 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.002 0.002 0.015 0.015 myscript.py:1(<module>)
[...]
non trovo l'uscita di linea di comando molto facile da leggere, così ho quasi sempre uso gprof2dot, che trasforma le informazioni di profilazione in un grafico abbastanza graphviz:
$ python -m cProfile -o myscript.prof myscript.py
$ python gprof2dot.py -o myscript.dot -f pstats myscript.prof
$ dot -Tpng -o profile.png prof_runtest.dot -Gbgcolor=black
Umm, non penso che in realtà importi più di una volta. In realtà sta solo testando le prestazioni della cache dei moduli di Python. 'reload (module)' non ha lo stesso comportamento di importare da zero. Per rispondere veramente alla domanda dell'autore è in realtà piuttosto difficile, a meno che il tempo di importare sia abbastanza grande da poter misurare una chiamata alla volta è ragionevole. –
Un modo per importare profili consiste nell'utilizzare il modulo profile_imports utilizzato in bzr source code:
# put those two lines at the top of your script
import profile_imports
profile_imports.install()
# display the results
profile_imports.log_stack_info(sys.stderr)
Oltre a fornire le tempistiche per le importazioni, questo stima anche il tempo necessario per compilare un'espressione regolare, che è spesso una causa significativa del rallentamento delle importazioni.
Mi sono imbattuto in questo problema di profilazione di una grande applicazione legacy con un tempo di avvio di più secondi. È relativamente semplice sostituire l'importatore incorporato con qualcosa che faccia qualche profilazione. Qui di seguito è un modo di mostrare hacky circa quanto tempo ogni modulo necessario per eseguire:
import os
import sys
import time
class ImportEventNode(object):
def __init__(self, name, start_time, children=None, end_time=None):
self.name = name
self.start_time = start_time
self.children = [] if children is None else children
self.end_time = end_time
def __repr__(self):
return 'ImportEventNode({self.name}, {self.start_time}, children={self.children}, end_time={self.end_time})'.format(self=self)
@property
def total_time(self):
return self.end_time - self.start_time
@property
def net_time(self):
return self.total_time - sum(child.total_time for child in self.children)
root_node = cur_node = None
all_nodes = []
old_import = __import__
def __import__(*args, **kwargs):
global root_node, cur_node
name = args[0]
if name not in sys.modules:
t0 = time.time()
if root_node is None:
root_node = prev_node = cur_node = lcur_node = ImportEventNode(args[0], t0)
else:
prev_node = cur_node
cur_node = lcur_node = ImportEventNode(name, t0)
prev_node.children.append(cur_node)
try:
ret = old_import(*args, **kwargs)
finally:
lcur_node.end_time = time.time()
all_nodes.append(lcur_node)
cur_node = prev_node
return ret
else:
return old_import(*args, **kwargs)
__builtins__.__import__ = __import__
In esecuzione su un semplice esempio, ecco come appare sul scipy.stats importazione:
:import scipy.stats
:
:nodes = sorted(all_nodes, key=(lambda x: x.net_time), reverse=True)
:for node in nodes[:10]:
: print(node.name, node.net_time)
:
:<EOF>
('pkg_resources', 0.08431100845336914)
('', 0.05861020088195801)
('decomp_schur', 0.016885995864868164)
('PIL', 0.0143890380859375)
('scipy.stats', 0.010602712631225586)
('pkg_resources._vendor.packaging.specifiers', 0.007072925567626953)
('add_newdocs', 0.00637507438659668)
('mtrand', 0.005497932434082031)
('scipy.sparse.linalg', 0.005171060562133789)
('scipy.linalg', 0.004471778869628906)
Varia. Si prega di fornire qualche scenario o situazione specifica. –
-1: ulteriori fatti sono stati inseriti nei commenti di risposta. Nuovi fatti dovrebbero essere messi nella domanda, non le risposte. –