Source code for mosaic.utilities.mosaicTiming
"""
A class that provides platform independent timing and function profiling utilities.
:Created: 4/10/2016
:Author: Arvind Balijepalli <arvind.balijepalli@nist.gov>
:License: See LICENSE.TXT
:ChangeLog:
.. line-block::
4/14/21 AB Windows fixes
6/17/16 AB Only profile functions in DeveloperMode. Log timing output.
4/10/16 AB Initial version
"""
import time
import sys
import mosaic
import mosaic.utilities.mosaicLogging as mlog
from mosaic.utilities.mosaicLogFormat import _d
__all__=["mosaicTiming"]
class timingData(dict):
"""
Store timing information for each function being profiled
"""
def __init__(self, funcname):
self["funcname"]=funcname
self["last"]=0
self["total"]=0
self["maxtime"]=0
self["counter"]=0
def _currentTime(self):
return [
"Timing for \"{0}\": iterations={1}, last={2:0.3f} ms",
self["funcname"],
self["counter"],
self["last"]
]
def _timingStatistics(self):
return [
"Summary timing for \"{0}\": iterations={1}, total={2:0.3f} ms, maximum={3:0.3f} ms, average={4:0.3f} ms",
self["funcname"],
self["counter"],
self["total"],
self["maxtime"],
self["total"]/float(self["counter"])
]
[docs]class mosaicTiming:
"""
Profile code by attaching an instance of this class to any function. All the methods in this class are valid for the function being profiled.
"""
def __init__(self):
"""
Initialize timing functions
"""
self.timingDataDict={}
if mosaic.DeveloperMode and mosaic.CodeProfiling !='none':
self.TimingEnabled=True
if mosaic.CodeProfiling=='summary':
self.TimingSummary=True
else:
self.TimingSummary=False
self.logger=mlog.mosaicLogging().getLogger(__name__)
else:
self.TimingEnabled=False
self.timingFunc=time.time
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
self.PrintStatistics()
[docs] def FunctionTiming(self, func):
"""
Pass the function to be profiled as an argument. Alternatively with python 2.4+, attach a decorator to the function being profiled.
:Parameters:
- `func` : function to be profiled
:Usage:
.. code-block:: python
funcTimer=mosaicTiming.mosaicTiming()
@funcTimer.FunctionTiming
def someFunc():
print 'doing something'
# summarize the profiling results for someFunc
funcTimer.PrintStatistics()
"""
def timing_wrapper(*args, **kwargs):
if self.TimingEnabled:
t1 = self.time()
res = func(*args, **kwargs)
t2 = self.time()
try:
funcTimingObj=self.timingDataDict[func.__name__]
except KeyError:
funcname=func.__name__
funcTimingObj=timingData(funcname)
self.timingDataDict[funcname]=funcTimingObj
self._updateTiming(funcTimingObj, t1, t2)
if not self.TimingSummary:
logger=mlog.mosaicLogging().getLogger(func.__name__)
logger.debug(_d(
"Timing: iterations={0}, total={1:0.3f} ms, last={2:0.3f} ms, maximum={3:0.3f} ms",
funcTimingObj["counter"],
funcTimingObj["total"],
funcTimingObj["last"],
funcTimingObj["maxtime"]
))
else:
res = func(*args, **kwargs)
return res
return timing_wrapper
[docs] def time(self):
"""
A platform independent timing function.
"""
return self.timingFunc()
[docs] def Reset(self, funcname=None):
"""
Reset all profiling data collected for a specified function or all stored functions.
"""
if funcname:
del self.timingDataDict[funcname]
else:
self.timingDataDict={}
[docs] def PrintCurrentTime(self):
"""
Print timing results of the most recent function call
"""
if self.TimingEnabled:
for k, v in list(self.timingDataDict.items()):
self.logger.debug( _d(*v._currentTime()) )
[docs] def PrintStatistics(self):
"""
Print average timing results of the function call
"""
if self.TimingEnabled:
for k, v in list(self.timingDataDict.items()):
try:
self.logger.debug( _d(*v._timingStatistics()) )
except ZeroDivisionError:
self.logger.error( "ERROR: No timing data is available.")
def _updateTiming(self, funcTimingObj, t1, t2):
last=(t2-t1)*1000.0
funcTimingObj["last"] = last
funcTimingObj["total"] += last
funcTimingObj["counter"] += 1
if last > funcTimingObj["maxtime"]: funcTimingObj["maxtime"]=last
if __name__ == '__main__':
with mosaicTiming() as funcTimer:
@funcTimer.FunctionTiming
def someFunc():
time.sleep(0.01)
for i in range(10):
someFunc()