^c<dZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl m Z ddl mZm Z ejZejZgdZhdZdZGd d ZeZGd d ZGd dZdZe jZdZdZdad.dZdZdZ dZ!d/dZ"edZ#GddZ$GddZ%d0dZ&d Z'd!Z(d/d"Z)d1d$Z*d2d%Z+iZ,d&Z-d'Z.d3d*Z/d+Z0d/d,Z1e2d-krej3e1dSdS)4a statprof is intended to be a fairly simple statistical profiler for python. It was ported directly from a statistical profiler for guile, also named statprof, available from guile-lib [0]. [0] http://wingolog.org/software/guile-lib/statprof/ To start profiling, call statprof.start(): >>> start() Then run whatever it is that you want to profile, for example: >>> import test.pystone; test.pystone.pystones() Then stop the profiling and print out the results: >>> stop() >>> display() % cumulative self time seconds seconds name 26.72 1.40 0.37 pystone.py:79:Proc0 13.79 0.56 0.19 pystone.py:133:Proc1 13.79 0.19 0.19 pystone.py:208:Proc8 10.34 0.16 0.14 pystone.py:229:Func2 6.90 0.10 0.10 pystone.py:45:__init__ 4.31 0.16 0.06 pystone.py:53:copy ... All of the numerical data is statistically approximate. In the following column descriptions, and in all of statprof, "time" refers to execution time (both user and system), not wall clock time. % time The percent of the time spent inside the procedure itself (not counting children). cumulative seconds The total number of seconds spent in the procedure, including children. self seconds The total number of seconds spent in the procedure itself (not counting children). name The name of the procedure. By default statprof keeps the data collected from previous runs. If you want to clear the collected data, call reset(): >>> reset() reset() can also be used to change the sampling frequency from the default of 1000 Hz. For example, to tell statprof to sample 50 times a second: >>> reset(50) This means that statprof will sample the call stack after every 1/50 of a second of user + system time spent running on behalf of the python process. When your process is idle (for example, blocking in a read(), as is the case at the listener), the clock does not advance. For this reason statprof is not currently not suitable for profiling io-bound operations. The profiler uses the hash of the code object itself to identify the procedures, so it won't confuse different procedures with the same name. They will show up as two different rows in the output. Right now the profiler is quite simplistic. I cannot provide call-graphs or other higher level information. What you see in the table is pretty much all there is. Patches are welcome :-) Threading --------- Because signals only get delivered to the main thread in Python, statprof only profiles the main thread. However because the time reporting function uses per-process timers, the results can be significantly off if other threads' work patterns are not similar to the main thread's work patterns. N)open)encodingpycompat)sstartsstopsresetsdisplaysprofile> util.py:checkhg.py:dispatch.py:runpager.py:pagecmdcolor.py:colorcmddispatch.py:dispatch.py:dispatchdispatch.py:_dispatchdispatch.py:_runcatchdispatch.py:checkargsextensions.py:closuredispatch.py:runcommanddispatch.py:_runcommandevolve.py:warnobserrorscZtj}|d|dz|dfS)Nrr)ostimes)rs 4/usr/lib/python3/dist-packages/mercurial/statprof.pyclockrs) HJJE !HuQx q **c@eZdZddZddZdZdZedZdS) ProfileStateNc>||d|_dS)Ncpu)resettrackself frequencys r__init__zProfileState.__init__s 9 rcd|_d|_|r d|z |_ntj|dsd|_n d|_d|_g|_dS)N)r'g?sample_intervalMbP?r)accumulated_timelast_start_timer(rhasattrremaining_prof_time profile_levelsamplesr"s rr zProfileState.resetsj *#  #&?D !$(9:: #/D  #'  rc|d|jdz |d|jdz f}|jd|dz|jd|dzf|_dSNrr)r+r*)r# stop_time increments raccumulate_timezProfileState.accumulate_timesk aL4/2 2 aL4/2 2  !! $y| 3  !! $y| 3! rcP|j|jt|jz SN)r*timeidxlenr/r#s rseconds_per_samplezProfileState.seconds_per_samples!$T\2S5F5FFFrc |jdkrdSdS)Nsrealrr)r!r9s rr7zProfileState.timeidxs : 1qrr6) __name__ __module__ __qualname__r%r r4r:propertyr7rrrrsx(   GGGXrrcPeZdZiZdZdZdZdZedZ dZ dZ dZ d S) CodeSite)pathlinenofunctionsourcect|tsJ||_||_t|tsJ||_d|_dSr6) isinstancebytesrCrDrErF)r#rCrDrEs rr%zCodeSite.__init__sN$&&&&&  (E*****   rcT |j|jko|j|jkS#YdSxYw)NF)rDrC)r#others r__eq__zCodeSite.__eq__s4 ;%,.J49 3J J 55s"'c8t|j|jfSr6)hashrDrCr9s r__hash__zCodeSite.__hash__sT[$),---rcx||f} |j|S#t$r||||}||j|<|cYSwxYwr6)cacheKeyError)clsrCrDrEkvs rgetz CodeSite.gets^ 6N 9Q<    D&(++ACIaLHHH s #99cp|j |jdz }t|jd5}t |D]&\}}||kr||_n'dddn #1swxYwYn#YnxYw|jd|_|j}t ||kr|d|dz dz}|S)Nrrbrs...)rFrDrrC enumeratestripr8)r#lengthrDfpilinerFs r getsourcezCodeSite.getsources  ;  q$)U++"r#,R==""4;;*.**,,DK!E'"""""""""""""""  {"!  v;;  NvzN+f4F s.A77A+ A7+A//A72A/3A77A;cJtj|jSr6)rrCbasenamer9s rfilenamezCodeSite.filenamesw ***rc>|d|jS)N:)rcrEr9s rskipnamezCodeSite.skipnames--////4==99rN) r<r=r>rQ __slots__r%rLrO classmethodrVr`rcrfr@rrrBrBs E8I ...[&+++:::::rrBc.eZdZdZdZedZdS)Samplestacktimec"||_||_dSr6rk)r#rlrms rr%zSample.__init__ s  rc g}|ru|ttj|jj|jtj|jj|j }|ut||Sr6) appendrBrVrsysbytesf_code co_filenamef_linenoco_namef_backrj)rSframermrls r from_framezSample.from_frames ! LL %el&>??N%el&:;;   LE !eT"""rN)r<r=r>rgr%rhrxr@rrrjrjsC!I # #[ # # #rrjctjdkrt}t|tjtj}tjt ||tj tj tj d|t_dSdS)Nrr')stater.rr4r*r7r/rprjrxsignal setitimer ITIMER_PROFr(r+)signumrwnow timestamps rprofile_signal_handlerr#s Qgg c"""*5=9  V..ui@@AAA+U-BCHHH #rctst}t|t j|}tjtj}tj t |||t_ tjtjttdSr6) stopthreadis_setrrzr4sys_current_framesr*r7r/rprjrxr+rmsleepr(clear)tidrrwrs r samplerthreadr2s!! *gg c"""#%%c**5=9  V..ui@@AAA # 5()))!! *rc"tjdkSNr)rzr.r@rr is_activerFs   ""rthreadrc|t_txjdz c_tjdkr!tt_tj}dt_|a|dkrRtjtjttj tj |p tj ddS|dkrtjfdtjDd}t%jt(|fd t_tjdSdSdS) z:Install the profiling signal handler, and start profiling.rNsignalr'rc&g|] \}}|k |Sr@r@).0rTfrws r zstart..`s"MMMA!u**1***rrr)targetargsname)rzr!r.rr+r- lastmechanismr{SIGPROFrr|r}r(inspect currentframerritems threadingThreadrthreadstart) mechanismr!rptrrws @rrrMs<EK 1 a %'$(!"  ! ! M&.*@ A A A  "C$@5+@#     ) # #(**EMMMM!4!6!6!!>MMMaPC$+$C6EL L   ' $ #rcrtxjdzc_tjdkr tdkr\tjtjdd}tjtjtj|dt_nBtdkr7t tj t tdt_t jd}|rt'|tS)z;Stop profiling, and uninstall the profiling signal handler.rrrr'rNs STATPROF_DEST)rzr.rr{r|r}rSIG_IGNr-rsetrjoinr4rr+renvironrV save_data)r statprofpaths rstoprgs 1 a I % %"6#5sC@@C M&.&. 9 9 9(+AE % % i ' ' NN    L      egg&&& $'++,<==  $ l # # # Lrc Jt|d5}|dtjztjD]I}|j}|j}d|D}|d|d|fzJ ddddS#1swxYwYdS)Nw+s%f %f cbg|],}d|jd|jz|jg-S)s%d)rrCrDrErss rrzsave_data..sF AFEAH$4ajABBrs%d%s )rwriterzr*r/rmrlr)rCfilesamplermrlsitess rrr|s dE   @d : 66777m @ @F;DLEE JJ{dEJJu,=,=%>> ? ? ? ? @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @sA9BBBc t|d}d|dDt_gt_|ddD]}|d}t|d}|dd}g}|D]e}|d}|t |dt|d|dftjt||dS)NrXc,g|]}t|Sr@)float)rvalues rrzload_data..sIIIueEllIIIrrrrr) rread splitlinessplitrzr*r/rrprBrVintrj) rClinesr_partsrmrawsitesrrawsite sitepartss r load_datars. u   " " $ $ / / 1 1EIIa8H8HIIIEEMabb 2 2 5!!U1X9  G e,,I LL Yq\3y|+<+.s***a***r)rZrlrVrrrvalues)rSr/statsrr^rsitestats r buildstatszSiteStats.buildstatss ' 'F$V\22 ' '4 99T??+(H"*E$K!!###66$$&&& '+*5<<>>****rN) r<r=r>r%rrrrrrrhrr@rrrrs 999:::;;;<<<++[+++rrc*eZdZdZdZdZdZdZdZdZ dS) DisplayFormatsrrrrYrN) r<r=r>ByLineByMethod AboutMethodHotpath FlameGraphJsonChromer@rrrrs1 FHKGJ D FFFrrrYc `|t}| ddlm}|j}t |jdkr|ddS|tjkrt||n|tj krt||n|tj krt||fi|n|tjkrt||fi|nn|tjkrt#||fi|nO|tjkrt'||n.|tjkrt+||fi|nt-d|tjtjfvr^|d|dt |jz|d |jzdSdS) z* * *$#### >- - -T2000000 >) ) )b++F++++ >, , ,tR**6**** >& & &dB >( ( (b++F++++0111 n)>+@AAA  &T\):)::;;; 69NNOOOOOBArct|j}|dd|ddz|ddz|D]}|j}d||j|jfz}|d | | | |fzd S) zsPrint the profiler data with each sample line represented as one row in a table. Sorted by self-time per line.Tc*|Sr6rxs rz!display_by_line..s1==??rreversekey%5.5s %10.10s %7.7s %-8.8s s% s cumulativesselfr%5.5s %9.9s %8.8s %-8.8s stimesecondsr snames%s:%d:%s%6.2f %9.2f %9.2f %s N) rrr/sortrrrcrDrErrr)rr]rstatr sitelabels rrrs   . .E JJt!:!:J;;;HH* / 0HH( 4 5    y4==??DK"OO   &  ""!!##  ""         rc |ddz|ddzt|j}t t }|D]D}||jdz|jjz |Eg}| D]o\}}d}d} d} |D]G}|| z }| | z } | | z } H| ||| | |fp|dd |D]} | d d kr|d | d | d | d| dfz| ddd | dD]}| d kr|jd} t!| t"st%j| } | | |jj| f} |d| zdS)zPrint the profiler data with each sample function represented as one row in a table. Important lines within that function are output as nested rows. Sorted by self-time per line.rr r r :rTc|dS)Nrr@rs rrz#display_by_method..Ns !A$rrrY皙?r rrrc*|Sr6r)r^s rrz#display_by_method..]sQ]]__rs%33.0f%% %6.2f line %d: %s N)rrrr/ defaultdictlistrrcrErprrrrrr`rHrIrbytestrrD)rr]rgroupedr functiondatafname sitestats total_cum_sectotal_self_sec total_percentrErF stattuples rrr+sHH* / 0HH( 4 5   . .E$GOO ""$$t+di.@@AHHNNNNL#MMOO   y   0 0D T..00 0M d..00 0N T--// /MM M>=) L    d777 HH A;     &          +D+DEEEQK H HD!!A%%,,R00!&%006%-f55F$$&&$$&&I$  :YFGGG HHHrc tdddvrd\d}i}i}|jD]}t|jD]\}} | jkrzr| kr`|dz }|t|jdz kr(|j|dz} | |vr|| dz|| <nd|| <| |vr|| dz|| <d|| <d|D}| dd|D]\} } | d | |z d ztj | tj | j| jtj | d fzt |j} fd | D} d} d}d}d}| D]^}| |z } ||z }||z }||z }_| d tj pdtj | |||fzd|D}| dd|D]P\}} | d| |z d z|jtj |d fzQdS)NzInvalid functionrrrcg|] \}}||f Sr@r@)rparentcounts rrz(display_about_method..s DDD=65DDDrTc|dSrr@rs rrz&display_about_method..s QqTrrs%6.2f%% %s:%s line %s: %s r2crg|]3}|jjkr!r|jk1|4Sr@)rrErc)rrrcrEs rrz(display_about_method..sS    6?h & & 'V__..(:: ;::rsA %s:%s Total: %0.2fs (%0.2f%%) Self: %0.2fs (%0.2f%%) s___cg|] \}}||f Sr@r@)rchildr%s rrz(display_about_method..s DDD<5%DDDrc|dSrr@rs rrz&display_about_method..s adrs %6.2f%% line %s: %s )rrr/rZrlrErcr8rrrrfsencoderqrDr`rrrrrr)rr]rErrelevant_samplesparentschildrenrr^rr$r%rrrtotal_self_percenttotal_cum_percentrr*rcs ` @rrros*+++H x%^^D11(GH,'' .. ' 'GAt}(() $ 8 ; ; A% FL))A---#\!a%0F((*1&/A*=*+8##%-d^a%7HTNN%&HTN '"EDGMMOODDDG LL>>L222     .((3.!&//"3"344!&/22 !&"2"22"6"677      . .E        EMN11**,,, $**,,,d..000T..000HHO  h0& 1 1  h ' '          ED8>>3C3CDDDH MM$NNM333   u  .((3. !%//""5"566       rrc V Gfddd|jdj}|jD]5}|jddd|j|z |j}6|dd  fdjdkrdddSdS) Nc eZdZdZfdZdS) display_hotpath..HotNodec0||_d|_i|_dSr)rr%r/rs rr%z)display_hotpath..HotNode.__init__sDIDJDMMMrc(|xj|z c_|d}|j|}|s|}||j|<t|dkrd}|t|krZ||t vr9|dz }|t|kr!||t v9|t|kr |||d|dSdS|xj|z c_dSr1)r%r/rVr8rfskipsadd)r#rlrmrr*r^HotNodes rr8z$display_hotpath..HotNode.adds JJ$ JJ8DM%%d++E , &+ d#5zzA~~#e**nnq):):)<)<)E)EFA#e**nnq):):)<)<)E)Es5zz>>IIeABBi....."> t# rN)r<r=r>r%r8)r9srr9r4s=     $ $ $ $ $ $ $rr9rshowtimeTcx|j}fd|jD}|r|dzdz }|dzd}|j}d||rdndzd zr d |jzndzd z}||jjz d z||fz} td dt| z } d} | d krd} d} | | d | |j |j nddtdd tt|j z | dfz} | | z}td|jD}|j|z djzkr d|zdz}n|j|z dkrd|zdz}|dz|}t|dks|r|dz }|dd|D] }||t|dk!dS)Nc:g|]}|jjzk|Sr@r%)rclimitroots rrz3display_hotpath.._write..s3   UTZ=O1P1PA1P1P1Prrrrr\|s %4.1f%%s %5.2fss %s %srr7s, s %s%s %d: %s%ssliner:rcg|] }|j Sr@r>)rr?s rrz3display_hotpath.._write..s"K"K"Kq17"K"K"Krg?sss Tc|jSr6r>rs rrz1display_hotpath.._write..srr)rr/rrcljustrEr%maxr8rjustrDstrr`sumrr)nodedepthmultiple_siblingsrvisiblechildrenindentrcrE listpattern liststring spacing_lenprefix codepattern codestring finalstringchildrensamplesnewdepthr*_writer]r@rAr;s rr]zdisplay_hotpath.._writesy     }++--    ) *QY]F $.55b99H}H &!!-75549/7?: **CA  % TZ'#-(J ac*oo!566KFa*K$ k**#{6 B #aST[)9)9%:%:!:;;<<r"" (J%z1K!"K"KDM4H4H4J4J"K"K"KLLOzO+sTZ/?@@)K7*D o-22)K7*D HH[5( ) ) )   ! # #'8 # MHT/@/@AAA$ > >E F5(C$8$81$< = = = = > >rF)r/rmr8rlrVr%) rr]r@rlasttimerr9r]rAr;s `` @@@@rrrs$$$$$$$$$$2 74==D|A#H, ddd#V[8%;<<<;zz*d++H6>6>6>6>6>6>6>6>6>p zA~~tQ~rc |tjddz}tj|s/|d|z|ddSi}|jD]T}d|jD}|d |}||vr||dz||<Od||<Utj \} } t| d5} | D]\}} | d || fz dddn #1swxYwY|d }tjd | |fz|d |zdS) NsHOMEs/flamegraph.plserror: missing %s s8get it here: https://github.com/brendangregg/FlameGraph cg|] }|j Sr@)rErs rrz"write_to_flame..-s222222r;rrs%s %d s~/flamegraph.svgsperl ~/flamegraph.pl %s > %ssWritten to %s )rrrrCexistsrr/rlrrrmkstemprrsystem) rr] scriptpath outputfilerrrrr_fdrCrr%s rrr#s%g.1BB 7>>* % % '*4555 MNNN E,22V\222 yy 5==+/E$KKE$KK!!HB dE  3d ;;== 3 3KD% JJzT5M1 2 2 2 2 3333333333333333( I-z0BBCCCHH * ,-----s*5D,,D03D0cF|tvr t|Stjtjdd}|gt jzD]?}|tjz}||r|t|d}n@|t|<|S)zAttempt to make the path to a Python module easier to read by removing whatever part of the Python search path it was found on.rrN) _pathcacher__file__rsplitrseprrC startswithr8)rChgpathprWs r simplifypathrpEs  z$   % %bfa 0 0 3FX RV ??6 " " F &D E Jt Krc g}|jD]u}g}|jD]M}|tj|j|jtj|jfN||j|fvtj |}t|ts| d}||dS)Nutf-8)r/rlrprsysstrrCrDrErmjsondumpsrHrIencoder)rr]r/rrlrws rrrVsG, - -\  E LLOEJ//LOEN33      U+,,,, :g  D dE " "${{7##HHTNNNNNr{Gzt?+?c gtjtjigfddt|jdj|jdjz }|zt |zf d}|jD]Ot djD}tj|}|kr<rR|rPd|dkr>|r|rd|dk>r | t|D]} jtf ||\} } t }  td| | jdz| d tj|Qr | fd tD} tjd tD} t!jt| | d }t%|t&s|d}|||ddS)Nc$|sdS|vr|S|dd}t}||<t|ddd|dz|d||S)Nrrz%s %s)categoryrr:)r$)r8rpdictupdate)rlr$myidid2stackstack2idstackids rrz write_to_chrome..stackidys  F H  E? "qrr##8}}eAhqk%(8JKKKLLL   RL  v  . . . rr)r:rc | t } \}} \}} j|z } |cxkr krHnnEt|z j}t d||||dzddS|dS)NE.Ar)phrcatsftspid)tuplepopleftrmrKrpr|r8)oldsidoldcatoldfuncoldtimeoldidxduration sampletime blacklistclamplastseen laststack maxthreshold minthresholdrr/rs rpoplastz write_to_chrome..poplastsy))**#++--"**,,;( 8 3 3 3 3| 3 3 3 3 3Wu_fk::J NN !C'       MM& ! ! ! ! !rc3K|]M}dttj|j|jfztj|jfVNdS)z%s:%dN)rprrsrCrDrE)rrws r z"write_to_chrome..sp    #HOEJ$?$?@@%,OPOEN33      rBr)rrrrrrc"g|] \}}|v | Sr@r@)ridxrrs rrz#write_to_chrome..s.398L8L8L8L8Lrc3>K|]\}}t||fVdSr6)rM)rrTrUs rrz"write_to_chrome..sA%%AQ %%%%%%r) traceEvents stackFramesr)rSrrrH) collectionsdequerr/rmrKrrlpopreversed appendleftr8rpr|rZ OrderedDictrtrurHrIrvr)rr]rr totaltimerrlqstackrrCrsideventsframesrrrrrrr/rrs `` @@@@@@@@@rrrns}G!##I ""H HH       & EI R % Q(<rs0NNb    % * ? ? ?   *+++********Z  7:7:7:7:7:7:7:7:t########8 $ $ $Y_      (### !!!!4* @ @ @222&(+(+(+(+(+(+(+(+V!P!P!P!PH   :AHAHAHHT T T T nZZZZz....> "0uuuup.A A A A H z CHTTVVr