# -*- coding: utf-8 -*-
#
# This file is subject to the terms and conditions defined in
# file 'LICENSE.txt', which is part of this source code package.
#
from typing import Dict, List, Union
import time
import functools
[docs]class Timer():
"""Utility class to measure time spend in the code
"""
almanac = {} # type: Dict[str, List[Union[float, int]] ]
def __init__(self, name=None):
self.name = name
self.startTime = 0.
self.stopTime = 0.
if not name in Timer.almanac:
# cumulative time and number of time called
Timer.almanac[name] = [0.,0]
def __enter__(self):
"""Context implementation
"""
self.Start()
def __exit__(self, type, value, traceback):
"""Context implementation
"""
self.Stop()
def __str__(self) -> str:
"""Return the time for the current instance if already used if no return PrintTimes
Returns
-------
str
a string with the times store internally
"""
if self.startTime == 0 and self.stopTime==0:
return self.PrintTimes()
res = ""
val = self.almanac[self.name]
res += "\n" + str(self.name) + ": " + str(time.time()-self.startTime if self.stopTime == 0 else self.stopTime-self.startTime ) +" ("+str(val[1])+") : " + '{:6.3e}'.format(val[0]) + " s (mean {:6.3e} s/call)".format(val[0]/val[1] )
return res
[docs] @classmethod
def PrintTimes(cls) -> str:
"""Return the times recorded by Timer in string format
Returns
-------
str
a string with all the data
"""
res = ""
for name, val in cls.almanac.items():
if name is None: continue
res += "\n" + str(name) + ": ("+str(val[1])+") : " + '{:6.3e}'.format(val[0]) + " s (mean {:6.3e} s/call)".format(val[0]/val[1] )
return res
[docs] def Start(self):
"""Start the timer for the current instance
Returns
-------
Timer
self
"""
self.startTime = time.time()
return self
[docs] def Stop(self):
"""Stop the timer for the current instance
Returns
-------
Timer
self
"""
self.stopTime = time.time()
data = Timer.almanac[self.name]
data[0] += self.GetDiffTime()
data[1] += 1
[docs] def Reset(self):
"""Reset the internal storage (all measured times)
"""
Timer.almanac = {}
[docs] def GetDiffTime(self) -> float:
"""Return the elapsed time measured by this instance
Returns
-------
float
the elapsed time measured by this instance
"""
return self.stopTime - self.startTime
def __call__(self,func):
"""Support using timer as decorator"""
@functools.wraps(func)
def wrapper_timer(*args, **kwargs):
with self:
return func(*args, **kwargs)
return wrapper_timer
[docs]def CheckIntegrity(GUI:bool=False):
from Muscat.Helpers.Timer import Timer
with Timer("os, sys import Time"):
import os
import sys
with Timer("Time to Solve"):
print('toto')
print(Timer.PrintTimes())
Timer().Reset()
with Timer("Time of 1 print"):
print('toto')
a = Timer("3 grouped prints").Start()
print("1 Mississippi")
print("2 Mississippi")
print("3 Mississippi")
a.Stop()
a = Timer("3 independent prints").Start()
print("1 Mississippi")
a.Stop()
a.Start()
print("2 Mississippi")
a.Stop()
a.Start()
print("3 Mississippi")
a.Stop()
@Timer(name='4 Mississippi')
def Print4():
for i in range(4):
print(f"{i}/4 Mississippi")
Print4()
print(Timer.PrintTimes())
print(a)
print(Timer())
return "ok"
if __name__ == '__main__': # pragma no coverage
print(CheckIntegrity( GUI=True))