Ho appena aggiunto questo alla documentazione NYTProf:
= head2 if e subroutine intervalli non corrispondono
NYTProf ha due profiler: una dichiarazione profiler che viene richiamato quando perl passa da una istruzione perl a un'altra e un profiler di subroutine che viene richiamato quando chiamate perl o restituisce da una subroutine.
I singoli timing istruzione per un subroutine di solito aggiungere fino a un po ' inferiore al tempo di esclusiva per il subroutine. Questo perché la gestione della chiamata di subroutine e i risparmi di ritorno sono inclusi nel tempo esclusivo per la subroutine. La differenza può essere solo un nuovo microsecondo ma che potrebbe diventare notevole per le subroutine che sono chiamate centinaia di migliaia di volte.
La dichiarazione profiler tiene traccia di come molto tempo è stato speso per le spese generali, come scrittura dati del profilo dichiarazione alla disco. Il profiler subroutine sottrae i costi generali che hanno accumulato tra l'immissione e lasciando la subroutine per fornire un profilo più preciso. Il profiler dell'istruzione è in genere molto veloce perché la maggior parte delle scritture viene bufferizzata per la compressione zip, quindi il profilatore per riga tende ad essere molto piccolo, spesso un singolo "tick". Il risultato è che l'overhead accumulato è piuttosto rumoroso. Questo diventa più significativo per le subroutine che vengono chiamate frequentemente e sono anche veloce. Questo può essere un altro, più piccolo, contributo alla discrepanza tra tempo di dichiarazione ed esclusivo volte.
Questo probabilmente spiega la differenza tra la somma della colonna temporale dell'istruzione (31,7 s) e il tempo esclusivo riportato per la subroutine (57,2 s). La differenza ammonta a circa 100 microsecondi per chiamata (che sembra un po 'alto, ma non in modo irragionevole).
Il profiler di istruzione tiene traccia di quanto tempo è stato speso per i costi generali, come scrivere i dati del profilo di istruzione su disco. Il profiler delle subroutine sottrae la differenza di costi generali tra l'ingresso e l'uscita dalla subroutine al fine di fornire un profilo più accurato.
Il profiler di istruzioni è in genere molto veloce perché la maggior parte delle scritture vengono bufferizzate per la compressione zip, quindi l'overhead del profiler per istruzione tende ad essere molto piccolo, spesso un singolo "tick". Il risultato è che l'overhead accumulato è piuttosto rumoroso. Ciò diventa più significativo per le subroutine chiamate frequentemente e anche veloci (in questo caso chiamate 250303 a 899μs/chiamata). Quindi sospetto che questo sia un altro, più piccolo, contributo alla discrepanza tra tempo di dichiarazione e tempi esclusivi.
Ancora più importante, ho anche aggiunto questa sezione:
= head2 Se Headline subroutine intervalli non corrispondono i Subs Chiamato
complesso volte subroutine sono riportati con un titolo come "spesi 10s (2 + 8) entro ... ". In questo esempio, 10 secondi sono stati spesi all'interno della subroutine (il "tempo inclusivo") e, di questo, 8 secondi sono stati spesi nelle subroutine chiamate da questo. Che lascia 2 secondi come il tempo trascorso in il codice di subroutine stesso (il "tempo esclusivo", a volte anche chiamato "self time").
Il rapporto mostra il codice sorgente di la subroutine. Le linee che effettuano chiamate ad altre subroutine sono annotate con con i dettagli del tempo trascorso nelle chiamate .
volte la somma dei tempi di chiamate effettuate dalle linee di codice nel subroutine è minore della tempo compreso esclusiva riportato titolo (10-2 = 8 secondi dell'esempio sopra) .
Quello che sta succedendo qui è che le chiamate verso altre subroutine sono stati fatti, ma NYTProf non è in grado di determinare la posizione chiamando correttamente in modo che le chiamate non compaiono nella relazione in posto giusto.
L'utilizzo di una versione precedente di perl è una causa (see below). Un altro sta chiamando le subroutine che escono tramite "goto & sub;" - più frequentemente riscontrato in sottotitoli AUTOLOAD e codice utilizzando il modulo Memoize .
In generale i tempi complessiva subroutine è preciso e dovrebbe essere di fiducia più che la somma della dichiarazione o nidificate temporizzazioni sub chiamata.
Il modulo Memoize è la causa principale della discrepanza nel report. Le chiamate a Memoize::__ANON__[...]
eseguono un sub generato da Memoize che assomiglia a sub { unshift @_, $cref; goto &_memoizer; }
. Quel goto &_memoizer
è implementato da perl come una sorta di ritorno al chiamante seguito da una chiamata al sub specificato, e questo è il modo in cui NYTProf lo profila.
La confusione è causato dal fatto che, anche se add_bit_to_map
in registrazione del chiamante della _memoizer
così il tempo nella chiamata viene aggiunto add_bit_to_map
, il file e linea numero della posizione della chiamata viene registrata come la posizione del goto
.
Potrebbe essere possibile migliorarlo in una versione futura.
Grazie per avermi spinto a indagare su questo e migliorare la documentazione.
Tim Bunce.
p.s. Raccomando di fare domande su NYTProf su mailing list.
Hmm, non ho una risposta per te, ma posso dire che ho visto discrepanze simili usando NYTProf. Ha riferito che il mio script è durato circa 5 minuti quando sono occorsi circa 10 secondi. Era sotto mod_perl. – jira
Puoi mostrarci uno screenshot del rapporto, o qualcos'altro in modo che possiamo vedere il caso particolare? –
@brian d foy: Ho aggiunto un collegamento ad alcuni dei miei output – mmccoo