\x89\x50\x4E\x47\x0D\x0A\x1A\x0A PNG  \x89\x50\x4E\x47\x0D\x0A\x1A\x0A  13\c@`sdZddlmZmZmZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlmZmZejZejZdddd d gZd d d dddddddddddhZdZdefdYZeZdefdYZdefdYZd Ze jZd!Zd"Z da"d#d$d%Z#d&Z$d'Z%d(Z&dd)Z'ed*Z(d+efd,YZ)d-d?d.YZ*dd/dd0Z+d1Z,d2Z-dd3Z.d4d5Z/ddd6Z0iZ1d7Z2d8Z3d9d:d;Z4d<Z5dd=Z6e7d>kre j8e6ndS(@s 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. i(tabsolute_importtdivisiontprint_functionNi(tencodingtpycompattstarttstoptresettdisplaytprofiles util.py:checksextensions.py:closurescolor.py:colorcmdsdispatch.py:checkargssdispatch.py:sdispatch.py:_runcatchsdispatch.py:_dispatchsdispatch.py:_runcommandspager.py:pagecmdsdispatch.py:runsdispatch.py:dispatchsdispatch.py:runcommandshg.py:sevolve.py:warnobserrorscC`s&tj}|d|d|dfS(Niii(tosttimes(R ((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pytclocks t ProfileStatecB`sAeZddZddZdZdZedZRS(cC`s|j|d|_dS(Ntcpu(Rttrack(tselft frequency((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt__init__s cC`sbd|_d|_|r(d||_nt|dsCd|_nd|_d|_g|_dS(Ngg?tsample_intervalg@@i(gggMbP?(taccumulated_timetNonetlast_start_timeRthasattrtremaining_prof_timet profile_leveltsamples(RR((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRs     cC`s[|d|jd|d|jdf}|jd|d|jd|df|_dS(Nii(RR(Rt stop_timet increment((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pytaccumulate_timescC`s|j|jt|jS(N(RttimeidxtlenR(R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pytseconds_per_samplescC`s|jdkrdSdS(Ntrealii(R(R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRsN( t__name__t __module__RRRRR tpropertyR(((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyR s    tCodeSitecB`sYeZiZd ZdZdZdZedZdZ d Z d Z RS( upathulinenoufunctionusourcecC`s(||_||_||_d|_dS(N(tpathtlinenotfunctionRtsource(RR&R'R(((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRs   cC`s5y&|j|jko$|j|jkSWntSXdS(N(R'R&tFalse(Rtother((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt__eq__s cC`st|j|jfS(N(thashR'R&(R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt__hash__scC`sS||f}y|j|SWn1tk rN||||}||j|<|SXdS(N(tcachetKeyError(tclsR&R'R(tktv((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pytgets   cC`s|jdkr|jd}d}z]yOt|j}x9t|D]+\}}||krD|j|_PqDqDWWnnXWd|r|jnX|jdkrd|_qn|j}t||kr||d d}n|S(Nitis...( R)RR'topenR&t enumeratetstriptcloseR(RtlengthR'tfptitlineR)((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt getsources(    cC`stjj|jS(N(R R&tbasename(R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pytfilenamescC`sd|j|jfS(Ns%s:%s(R@R((R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pytskipnames(upathulinenoufunctionusource( R"R#R/t __slots__RR,R.t classmethodR4R>R@RA(((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyR%s     tSamplecB`s&eZdZdZedZRS(ustackutimecC`s||_||_dS(N(tstackttime(RRERF((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyR s cC`sTg}x>|rF|jtj|jj|j|jj|j}q Wt||S(N( tappendR%R4tf_codet co_filenametf_linenotco_nametf_backRD(R1tframeRFRE((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt from_frames   (ustackutime(R"R#RBRRCRN(((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRDs cC`sztjdkrvt}tj|tjtj}tjjtj ||t j t j tj d|t_ndS(Nig(tstateRR RRRRRGRDRNtsignalt setitimert ITIMER_PROFRR(tsignumRMtnowt timestamp((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pytprofile_signal_handlers    cC`sx{tjs}t}tj|tj|}tjtj}tj j t j |||t_ tjtjqWtjdS(N(t stopthreadtis_setR RORtsyst_current_framesRRRRGRDRNRRFtsleepRtclear(ttidRTRMRU((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt samplerthread)s   cC`s tjdkS(Ni(ROR(((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt is_active;stthreadRcC`s|t_tjd7_tjdkrtt_tj}d t_|a|dkrtjtj t tj tj |ptj dq|dkrtj}gtjjD]\}}||kr|^qd}tjdtd|fdd t_tjjqnd S( s:Install the profiling signal handler, and start profiling.iRPgR`ittargettargstnameR^N(RORRR RRRt lastmechanismRPtSIGPROFRVRQRRRtinspectt currentframeRYRZtitemst threadingtThreadR^R`R(t mechanismRtrptRMR2tfR]((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyR?s"        ;cC`stjd8_tjdkrtdkrhtjtjdd}tjtjtj|dt_n&tdkrt j tj j ntj tdt_tjjd}|rt|qntS(s;Stop profiling, and uninstall the profiling signal handler.iiRPgR`t STATPROF_DESTN(RORRdRPRQRRRetSIG_IGNRRWtsetR`tjoinRR RRRtenvironR4t save_data(Rlt statprofpath((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRVs    c C`st|d}|jdtjx{tjD]p}|j}|j}g|D]+}dj|jd|j |j g^qO}|jd|dj|fq0WWdQXdS(Nsw+s%f %f ss%ds%d%s s( R6twriteRORRRFRERqR&R'R((R&tfiletsampleRFREtstsites((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRsjs  5c C`st|djj}g|djD]}t|^q,t_gt_x|dD]}|jd}t|d}|d}g}xK|D]C}|jd} |jt j | dt | d| dqWtjjt ||q[WdS(Ntriissi( R6treadt splitlinestsplittfloatRORRRGR%R4tintRD( R&tlinestvalueR=tpartsRFtrawsitesRytrawsitet siteparts((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt load_datats,    cC`stjjtj|dS(sClear out the state of the profiler. Do not call while the profiler is running. The optional frequency argument specifies the number of samples to collect per second.N(R%R/R\ROR(R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRs cc`s&tz dVWdttXdS(N(RRR(((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyR s  t SiteStatscB`sVeZdZdZdZdZdZdZdZe dZ RS(cC`s||_d|_d|_dS(Ni(tsitet selfcountt totalcount(RR((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRs  cC`s|jd7_dS(Ni(R(R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pytaddselfscC`s|jd7_dS(Ni(R(R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pytaddtotalscC`s|jttjdS(Nid(RRROR(R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt selfpercentscC`s|jttjdS(Nid(RRROR(R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt totalpercentscC`s|jtjS(N(RROR (R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt selfsecondsscC`s|jtjS(N(RROR (R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt totalsecondsscC`si}x|D]w}xnt|jD]]\}}|j|}|s]t|}|||ss%5.5s %10.10s %7.7s %-8.8s s% t cumulativeRR5s%5.5s %9.9s %8.8s %-8.8s RFtsecondsRcs%s:%d:%ss%6.2f %9.2f %9.2f %s N(s% RRR5(RFRRRc(RRRtsorttTrueRuRRtfsencodeR@R'tsysbytesR(RRR(RR;RtstatRt sitelabel((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRs     c C`sG|jdd|jddtj|j}tt}x6|D].}||jjd |jjj |qGWg}x|j D]{\}}d }d } d } x>|D]6}||j 7}| |j 7} | |j 7} qW|j ||| | |fqW|jd td dx|D]} | ddkrGq+n|jd| d| d| dtj| d f| djd td dx| dD]}|j dkr|jjd} tjjdkrt| t rtj| } n|j |j |jj| f} |jd| qqWq+WdS(sPrint 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.s%5.5s %10.10s %7.7s %-8.8s s% RRR5s%5.5s %9.9s %8.8s %-8.8s RFRRct:iRRcS`s|dS(Ni((R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyR)sig?s%6.2f %9.2f %9.2f %s iiicS`s |jS(N(R(R<((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyR4sis%33.0f%% %6.2f line %d: %s N(s% RRR5(RFRRRc(RuRRRt defaultdicttlistRR@R(RGt iteritemsRRRRRRRR>RYt version_infotmajort isinstancetbytestbytestrR'(RR;RtgroupedRt functiondatatfnamet sitestatst total_cum_secttotal_self_sect total_percentR(R)t stattuple((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRsP    ,    "c K`s|dkrtdnd}d|krE|jd\}}nd}i}i}x|jD]}xt|jD]\} } | j|krw| s| j|krw|d7}| t|jdkr |j| d} | |kr|| d|| WdS(NsInvalid functionRiiRRcS`s|dS(Ni((R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyR_ss%6.2f%% %s:%s line %s: %s idi2sA %s:%s Total: %0.2fs (%0.2f%%) Self: %0.2fs (%0.2f%%) t___cS`s|dS(Ni((R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRss %6.2f%% line %s: %s (RRR}RR7RER(R@RRRRRuRRRR'R>RRRRRRR(RR;R(RR@trelevant_samplestparentstchildrenRwR<RtparenttcountRRxRRttotal_self_percentttotal_cum_percentRtchild((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRAsr      +  ! (   + g?c `sdtffdYd|jdj}xA|jD]6}j|jddd|j||j}qBWfdjdkrdtndS(NtHotNodec`s eZdZfdZRS(cS`s||_d|_i|_dS(Ni(RRR(RR((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRs  c`s|j|7_|d}|jj|}|sM|}||j|tsumRuRR(tnodetdepthtmultiple_siblingsRtctvisiblechildrentindentR@R(t childsitet listpatternt liststringt codepatternt codestringt finalstringtchildrensamplestnewdepthR(t_writeR;tlimittroot(s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRs< "   +  (tobjectRRRFRRERR*(RR;RRtlasttimeRw((RRR;RRs8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRs ' (cK`sq|dkr tjdd}ntjj|sT|jd||jddStj\}}t |d}i}xt|j D]i} g| j D]} | j ^q} | j dj| } | |kr|| d|| %ssWritten to %s (RRRrR R&texistsRuRtmkstempR6RRER(RRqRR9tsystem(RR;t scriptpatht outputfileRtfdR&RvRRwRxRyR=R((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRs.       cC`s|tkrt|Stjtjjtjdd}xH|gtj D]6}|tj}|j |rJ|t |}PqJqJW|t|<|S(sAttempt to make the path to a Python module easier to read by removing whatever part of the Python search path it was found on.ii( t _pathcacheRRRt__file__trsplitR tsepRYR&t startswithR(R&thgpathtptprefix((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt simplifypaths %  cC`sg}x`|jD]U}g}x0|jD]%}|j|j|j|jfq&W|j|j|fqWtj|}t |t s|j d}n|j |dS(Nsutf-8( RRERGR&R'R(RFtjsontdumpsRRtencodeRu(RR;RRwRERM((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRs#g{Gzt?g+?c`sgtjtji g fd d}dt|jdj|jdj}|t| f d}xg|jD]\jd}|j}t|j } t djD} tj| } | kr(qnx8rb| rbd| dkrbj | j q+Wxrv|qfWxt | D]} j jtfj | | \} } t } jtdd d |d | d jd d| ddqWtj| qWxr6|q&WgtD] }|dkrD|d^qD}tjdtD}tjtd|d||dd|jddS(Nc`s|s dS|kr|S|d}t}||<jtd|dddd|d|dk rdjd|n|S(NitcategoryiRcs%s %siR(RRGtdictRtupdate(RERtmyid(tid2stacktstack2idtstackid(s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRs   , cS`s!t|t| t|kS(N(RR(tatb((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pytendswith,sgMbP?iic`st}j\}}j\}}j|}|koZknrt|j}jtddd|d|d|d|ddd n j|dS( NtphtERctcattsfttsg.Atpidi(ttupletpopleftRFtmaxRGRR(toldsidtoldcattoldfunctoldtimetoldidxtdurationt sampletime( t blacklisttclamptlastseent laststackt maxthresholdt minthresholdRwRR(s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pytpoplastEs $cs`s4|]*}dt|j|jf|jfVqdS(s%s:%dN(RR&R'R((t.0RM((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pys YsRtBRcR R g.AR R ics`s'|]\}}t||fVqdS(N(R(RR2R3((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pys nst traceEventst stackFramesRs (t collectionstdequeRpRRFRRER(RR&Rtpoptreversedt appendleftRRGRR7t OrderedDictRtdumpRu(RR;RRRt totaltimeRttosRcR&REtqstackRmtsidRxteventstframes(( RRRRRRRRwRRRs8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyRsT     '    #     +  3 %cC`stddS(Ns The statprof command line allows you to inspect the last profile's results in the following forms: usage: hotpath [-l --limit percent] Shows a graph of calls with the percent of time each takes. Red calls take over 10%% of the total time themselves. lines Shows the actual sampled lines. functions Shows the samples grouped by function. function [filename:]functionname Shows the callers and callees of a particular function. flame [-s --script-path] [-o --output-file path] Writes out a flamegraph to output-file (defaults to ~/flamegraph.svg) Requires that ~/flamegraph.pl exist. (Specify alternate script path with --script-path.)(tprint(((s8/usr/lib64/python2.7/site-packages/mercurial/statprof.pyt printusagessc C`sF|dkrtj}nt|dkr5tdSi}d}d|d<|ddkrktj|dgsz              , <       * "  9 H H!  _  @