B t `F@sddlZddlZddlZdZejdkr.ejZnejdrBej ZnejZGddde Z e Z e j Z e jZGddde ZGd d d e ZdS) N) TicTocTimertictoc)rwinc@s>eZdZdZdddZdddZddd Zd d Zd d ZdS)raA class to calculate and report elapsed time. Examples: >>> from pyutilib.misc.timing import TicTocTimer >>> timer = TicTocTimer() >>> timer.tic('starting timer') # starts the elapsed time timer (from 0) >>> # ... do task 1 >>> timer.toc('task 1') # prints the elapsed time for task 1 If no ostream or logger is provided, then output is printed to sys.stdout Args: ostream (FILE): an optional output stream to print the timing information logger (Logger): an optional output stream using the python logging package. Note: timing logged using logger.info NcCs*t|_|_||_||_d|_d|_dS)Nr) _time_source _lastTime _loadTime_ostream_logger _start_count_cumul)selfostreamloggerr8/tmp/pip-unpacked-wheel-cqckmaqz/pyutilib/misc/timing.py__init__4s zTicTocTimer.__init__cCs.t|_|dkrd}|r*|j|d||ddS)a)Reset the tic/toc delta timer. This resets the reference time from which the next delta time is calculated to the current time. Args: msg (str): The message to print out. If :const:`None` (default), then prints out "Resetting the tic/toc delta timer"; if it evaluates to :const:`False` (:const:`0`, :const:`False`, :const:`""`) then no message is printed. ostream (FILE): an optional output stream (overrides the ostream provided when the class was constructed). logger (Logger): an optional output stream using the python logging package (overrides the ostream provided when the class was constructed). Note: timing logged using logger.info Nz!Resetting the tic/toc delta timerF)msgdeltarr)rrr)rrrrrrrr;s zTicTocTimer.ticTcCs|dkr$dtjddddd}t}|js:|jdkrl|j}|jrV|t|j7}|rd||j|f}n@|r||j}||_|rd||f}n||j}|rd ||f}|r |dkr|j}|dkr|dkrtj }|dk r| ||dkr|j }|dk r | ||S) aEPrint out the elapsed time. This resets the reference time from which the next delta time is calculated to the current time. Args: msg (str): The message to print out. If :const:`None` (default), then print out the file name, line number, and function that called this method; if it evaluates to :const:`False` (:const:`0`, :const:`False`, :const:`""`) then no message is printed. delta (bool): print out the elapsed wall clock time since the last call to :meth:`tic` or :meth:`toc` (:const:`True` (default)) or since the module was first loaded (:const:`False`). ostream (FILE): an optional output stream (overrides the ostream provided when the class was constructed). logger (Logger): an optional output stream using the python logging package (overrides the ostream provided when the class was constructed). Note: timing logged using logger.info NzFile "%s", line %s in %s)limitrrz[%8.2f|%4d] %s z [+%7.2f] %s z [%8.2f] %s ) traceback extract_stackrr rr r r sysstdoutwriter info)rrrrrnowZansrrrrSs<      zTicTocTimer.toccCsRyt|j}Wn(tk r8|jdkr2tdYnX|j|7_d|_|S)Nz/Stopping a TicTocTimer that was already stopped)rr TypeError RuntimeErrorr )rrrrrstops zTicTocTimer.stopcCs(|jr||jd7_t|_dS)N)rr!r r)rrrrstartszTicTocTimer.start)NN)NNN)NTNN) __name__ __module__ __qualname____doc__rrrr!r#rrrrr"s    ; rc@s,eZdZddZddZddZddZd S) _HierarchicalHelpercCs t|_t|_d|_d|_dS)Nr)rtic_tocdicttimers total_timen_calls)rrrrrsz_HierarchicalHelper.__init__cCs|jd7_|jdS)Nr")r-r)r#)rrrrr#sz_HierarchicalHelper.startcCs|j|j7_dS)N)r,r)r!)rrrrr!sz_HierarchicalHelper.stopc CsJd}t|jdkrF|dt|dd}||7}dtt|d}|j}|dd}x|jD]\}} |jdkr| j|jd } ntd } ||7}||d j|| j| j| j| j| d 7}|| j |d |d|d7}|| j8}qfW|jdkr ||jd } ntd } ||7}||djdd|d| d 7}|| dd7}|S)Nr-$ z{name:<}r"dnanz={ncalls:>9d} {cumtime:>9.3f} {percall:>9.3f} {percent:>6.1f} )namencallscumtimepercallpercent )indentstage_identifier_lengthsz9{ncalls:>9} {cumtime:>9.3f} {percall:>9} {percent:>6.1f} otherzn/a=) lenr+sumstrr,itemsfloatformatr-to_strreplace) rr;r<s underlinename_formatterZ other_timesub_stage_identifier_lengthsr5timerZ_percentrrrrEsD         z_HierarchicalHelper.to_strN)r$r%r&rr#r!rErrrrr(sr(c@sreZdZdZddZdddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZddZdS)HierarchicalTimera A class for hierarchical timing. Examples -------- >>> import time >>> from pyutilib.misc.timing import HierarchicalTimer >>> timer = HierarchicalTimer() >>> timer.start('all') >>> time.sleep(0.2) >>> for i in range(10): ... timer.start('a') ... time.sleep(0.1) ... for i in range(5): ... timer.start('aa') ... time.sleep(0.01) ... timer.stop('aa') ... timer.start('ab') ... timer.stop('ab') ... timer.stop('a') ... >>> for i in range(10): ... timer.start('b') ... time.sleep(0.02) ... timer.stop('b') ... >>> timer.stop('all') >>> print(timer) Identifier ncalls cumtime percall % --------------------------------------------------- all 1 2.248 2.248 100.0 ---------------------------------------------- a 10 1.787 0.179 79.5 ----------------------------------------- aa 50 0.733 0.015 41.0 ab 10 0.000 0.000 0.0 other n/a 1.055 n/a 59.0 ========================================= b 10 0.248 0.025 11.0 other n/a 0.213 n/a 9.5 ============================================== =================================================== The columns are: ncalls : The number of times the timer was started and stopped cumtime: The cumulative time (in seconds) the timer was active (started but not stopped) percall: cumtime (in seconds) / ncalls % : This is cumtime of the timer divided by cumtime of the parent timer times 100 >>> print('a total time: %f' % timer.get_total_time('all.a')) a total time: 1.902037 >>> print('ab num calls: %d' % timer.get_num_calls('all.a.ab')) ab num calls: 10 >>> print('aa %% time: %f' % timer.get_relative_percent_time('all.a.aa')) aa % time: 44.144148 >>> print('aa %% total: %f' % timer.get_total_percent_time('all.a.aa')) aa % total: 35.976058 Internal Workings ----------------- The HierarchicalTimer use a stack to track which timers are active at any point in time. Additionally, each timer has a dictionary of timers for its children timers. Consider >>> timer = HierarchicalTimer() >>> timer.start('all') >>> timer.start('a') >>> timer.start('aa') After the above code is run, self.stack will be ['all', 'a', 'aa'] and self.timers will have one key, 'all' and one value which will be a _HierarchicalHelper. The _HierarchicalHelper has its own timers dictionary: {'a': _HierarchicalHelper} and so on. This way, we can easily access any timer with something that looks like the stack. The logic is recursive (although the code is not). cCst|_t|_dS)N)liststackr*r+)rrrrr2szHierarchicalTimer.__init__FcCsZ||j}||jkr |j|S|r@tdd|j|gt|j|<|j|SdS)a This method gets the timer associated with the current state of self.stack and the specified identifier. Parameters ---------- identifier: str The name of the timer should_exist: bool The should_exist is True, and the timer does not already exist, an error will be raised. If should_exist is False, and the timer does not already exist, a new timer will be made. Returns ------- timer: _HierarchicalHelper zCould not find timer {0}.N)_get_timer_from_stackrNr+r rDjoinr()r identifier should_existparentrrr _get_timer6s    zHierarchicalTimer._get_timercCs"||}||j|dS)z Start incrementing the timer identified with identifier Parameters ---------- identifier: str The name of the timer N)rUr#rNappend)rrRrKrrrr#Us zHierarchicalTimer.startcCsN||jdkr*tt|dd|j|j|j|dd}|dS)z Stop incrementing the timer identified with identifier Parameters ---------- identifier: str The name of the timer zU is not the currently active timer. The only timer that can currently be stopped is rOT)rSN)rN ValueErrorrArQpoprUr!)rrRrKrrrr!bs  zHierarchicalTimer.stopcCst|j}t}xht|dkr|t}d}x4|D],\}}||jt||kr2t|}q2W|t|td|}qW|S)Nrr=)rMr+rBr?extendrVmax)rZ stage_timersZ stage_lengthsZnew_stage_timersmax_lenrRrKrrr_get_identifier_lents  z%HierarchicalTimer._get_identifier_lenc Cs|}dtt|d}|djdddddd }d t|d d }||7}|d d}x^|jD]P\}}||dj||j|j|j|j||d 7}||j d|d|d7}qhW|| d d7}|S)Nz{name:9} {cumtime:>9} {percall:>9} {percent:>6} Z Identifierr6r7r8%)r5r6r7r8r9r/r0r1r"z={ncalls:>9d} {cumtime:>9.3f} {percall:>9.3f} {percent:>6.1f} r:r)r;r<r>) r]rAr@rDr+rBr-r,get_total_percent_timerErF)rr<rIrGrHrJr5rKrrr__str__s.    zHierarchicalTimer.__str__cCst|_t|_dS)z- Completely reset the timer. N)rMrNr*r+)rrrrresetszHierarchicalTimer.resetcCs |}x|D]}|j|}q W|S)z This method gets the timer associated with stack. Parameters ---------- stack: list of str A list of identifiers. Returns ------- timer: _HierarchicalHelper )r+)rrNtmpirrrrPs  z'HierarchicalTimer._get_timer_from_stackcCs|d}||}|jS)a$ Parameters ---------- identifier: str The full name of the timer including parent timers separated with dots. Returns ------- total_time: float The total time spent with the specified timer active. rO)splitrPr,)rrRrNrKrrrget_total_times  z HierarchicalTimer.get_total_timecCs|d}||}|jS)a) Parameters ---------- identifier: str The full name of the timer including parent timers separated with dots. Returns ------- num_calss: int The number of times start was called for the specified timer. rO)rdrPr-)rrRrNrKrrr get_num_callss  zHierarchicalTimer.get_num_callscCs^|d}||}||dd}||kr8||S|jdkrR|j|jdStdSdS)aW Parameters ---------- identifier: str The full name of the timer including parent timers separated with dots. Returns ------- percent_time: float The percent of time spent in the specified timer relative to the timer's immediate parent. rONrWrr3r4)rdrPr_r,rC)rrRrNrKrTrrrget_relative_percent_times    z+HierarchicalTimer.get_relative_percent_timecCsX|d}||}d}x|jD]}||j7}q$W|dkrL|j|dStdSdS)aW Parameters ---------- identifier: str The full name of the timer including parent timers separated with dots. Returns ------- percent_time: float The percent of time spent in the specified timer relative to the total time in all timers. rOrr3r4N)rdrPr+valuesr,rC)rrRrNrKr,Z_timerrrrr_s  z(HierarchicalTimer.get_total_percent_timeN)F)r$r%r&r'rrUr#r!r]r`rarPrerfrgr_rrrrrLsT  rL)rtimer__all__ version_info perf_counterrplatform startswithclockobjectrZ _globalTimerrrr(rLrrrr s  ~8