import sys from datetime import datetime, timedelta from cStringIO import StringIO locked = False timestamp = None err_stream = None nest = 0 EPSILON = timedelta(seconds=.05) INSPECTING = False if INSPECTING: import inspect class benchmarking(object): # Pass offset to include the caller (offset stack frames up) in the msg def __init__(self, desc, offset=None): self.desc = desc self.offset = offset def __enter__(self): global timestamp, nest if not locked: return if timestamp is not None: newts = datetime.now() delta = newts - timestamp if delta > EPSILON: print >>err_stream, ' '*nest, '# Time elapsed:', delta desc = self.desc if self.offset is not None and INSPECTING: caller = inspect.stack()[1 + self.offset][1:4] caller = (caller[0].rsplit('/', 1)[-1],) + caller[1:] desc += ' for %s' % (caller,) print >>err_stream, ' '*nest, 'Start', desc nest += 1 timestamp = newts self.starttime = newts def __exit__(self, exc_type, exc_val, exc_tb): global timestamp, nest if not locked: return if timestamp is not None: newts = datetime.now() delta = newts - timestamp if delta > EPSILON: print >>err_stream, ' '*nest, '# Time elapsed:', delta nest -= 1 print >>err_stream, ' '*nest, 'End', self.desc, '(took %s)' % (newts - self.starttime) timestamp = newts @staticmethod def info(msg): if locked: print >>err_stream, ' '*nest, msg @staticmethod def start(err=sys.stderr, prevent_override=False): global timestamp, err_stream, locked if not locked: timestamp = datetime.now() err_stream = err if prevent_override: locked = True