2009-04-20 1 views
9

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

+0

Varia. Si prega di fornire qualche scenario o situazione specifica. –

+0

-1: ulteriori fatti sono stati inseriti nei commenti di risposta. Nuovi fatti dovrebbero essere messi nella domanda, non le risposte. –

risposta

5

È 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?

+0

Ho uno script master che importa altri moduli. Devo calcolare quanto tempo ci vuole – user46646

+0

@rejinacm: Si prega di aggiornare la domanda con nuovi fatti. –

1

Uso Cprofile:

python -m cProfile yourscript.py 
+0

Sto usando IDLE. Sto ottenendo SyntaxError – user46646

+0

Il comando che ho dato sarebbe quello che avresti eseguito dalla riga di comando, non dall'interno dell'interprete python. – vezult

0

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 
3

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 

Example output (1429x1896px PNG)

+0

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. –

6

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.

0

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)