Il modulo profile è un modulo della libreria standard di Python, ci dà la possibilità di vedere il tempo di esecuzione delle funzioni che chiamiamo o altre parti di codice, visualizzerà inoltre delle statistiche sulle prestazioni, sul numero di funzioni chiamate, sul tempo di esecuzione e quant'altro.

Sui sistemi Unix-like possiamo dare

 

time script.py

per avere il tempo di esecuzione dei programmi ecc, ma usando profile, come detto prima, abbiamo delle statistiche più o meno complete sul nostro script o solo sulla parte a noi interessata.

Veniamo al dunque, per prima cosa importiamo il modulo

 

import profile

Ora utilizziamo il metodo run a cui passiamo come parametro la parte di codice che vogliamo valutare

 

profile.run("print 'Hello World!'")

A questo punto, salviamo lo script ed eseguiamolo, vi si presenterà una schermata del genere

 

Hello World!
         154 function calls in 0.014 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        3    0.000    0.000    0.000    0.000 :0(acquire)
        3    0.000    0.000    0.000    0.000 :0(allocate_lock)
        3    0.000    0.000    0.000    0.000 :0(dumps)
        3    0.000    0.000    0.000    0.000 :0(fileno)
        3    0.000    0.000    0.000    0.000 :0(get)
       12    0.000    0.000    0.000    0.000 :0(get_ident)
        3    0.000    0.000    0.000    0.000 :0(getattr)
        6    0.000    0.000    0.000    0.000 :0(isinstance)
        9    0.000    0.000    0.000    0.000 :0(len)
        3    0.000    0.000    0.000    0.000 :0(pack)
        3    0.000    0.000    0.000    0.000 :0(release)
        3    0.000    0.000    0.000    0.000 :0(select)
        3    0.007    0.002    0.007    0.002 :0(send)
        1    0.002    0.002    0.002    0.002 :0(setprofile)
        1    0.000    0.000    0.012    0.012 :1()
        1    0.000    0.000    0.014    0.014 profile:0(print 'Hello World!')
        0    0.000             0.000          profile:0(profiler)
       21    0.000    0.000    0.000    0.000 rpc.py:149(debug)
        3    0.000    0.000    0.012    0.004 rpc.py:208(remotecall)
        3    0.000    0.000    0.011    0.004 rpc.py:218(asynccall)
        3    0.000    0.000    0.001    0.000 rpc.py:238(asyncreturn)
        3    0.000    0.000    0.000    0.000 rpc.py:244(decoderesponse)
        3    0.000    0.000    0.000    0.000 rpc.py:279(getresponse)
        3    0.000    0.000    0.000    0.000 rpc.py:287(_proxify)
        3    0.000    0.000    0.000    0.000 rpc.py:295(_getresponse)
        3    0.000    0.000    0.000    0.000 rpc.py:317(newseq)
        3    0.000    0.000    0.007    0.002 rpc.py:321(putmessage)
        3    0.000    0.000    0.005    0.002 rpc.py:546(__getattr__)
        2    0.000    0.000    0.000    0.000 rpc.py:589(__init__)
        2    0.000    0.000    0.007    0.004 rpc.py:594(__call__)
        3    0.000    0.000    0.000    0.000 socket.py:221(meth)
        3    0.000    0.000    0.000    0.000 threading.py:100(__init__)
        3    0.000    0.000    0.000    0.000 threading.py:115(acquire)
        3    0.000    0.000    0.000    0.000 threading.py:135(release)
        3    0.003    0.001    0.004    0.001 threading.py:175(Condition)
        3    0.000    0.000    0.000    0.000 threading.py:180(__init__)
        6    0.000    0.000    0.000    0.000 threading.py:58(__init__)
        6    0.000    0.000    0.000    0.000 threading.py:63(_note)
        6    0.000    0.000    0.000    0.000 threading.py:804(currentThread)
        3    0.000    0.000    0.000    0.000 threading.py:95(RLock)

Come si può osservare sono state chiamate un totale di 154 funzioni Python per un tempo complessivo di 0,014 secondi. Più in basso ci sono maggiori dettagli, numero di chiamate alle funzioni e relativi tempi di esecuzione, quali funzioni sono state chiamate, e così via.

Il tempo di esecuzione non è che sia proprio quello complessivo, perchè tiene conto solo della nostra chaiamta a profile.run(), ma nel dettaglio si possono vedere tutti i tempi di esecuzione di ogni funzione.

Altro esempio, scriviamo una semplice funzione per calcolare il fattoriale (spero sappiate di cosa parlo xD)

 

def fattoriale(n):
    fatt = 1
    for x in range(1, n+1):
        fatt = fatt*x
        print '!'+str(x)+'\t=\t', fatt

A questo punto diamo come prima un bel

 

profile.run('fattoriale(10)')

Vedrete che il tempo di esecuzione sarà chiaramente maggiore del precedente in quanto deve fare alcuni calcoli ed eseguire un ciclo.

Come si può notare basta passare a run il codice che volete (scrivetelo sempre dentro gli apici, perché accetta i parametri come strighe) e così avrete una mano per determinare quali parti di codice causano i così detti colli di bottiglia e avere così un aiuto nell'ottimizzazione dei vostri script.

 

freenet