# -*- 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.#importcProfileimportpstatsimportiofromcollectionsimportOrderedDictimportnumpyasnpfromMuscat.Helpers.InterpolationimportBinarySearch
[docs]classProfiler():"""Class to help profiling code, this is a very simple approach. it uses cProfile and pstats to do all the work. myProfiler = Profiler(0.2) myProfiler.Start() #do some work time.sleep(0.02) print("Hello") a = 3 + 4 myProfiler.Stop() print(myProfiler) """def__init__(self,discardedPortion:float=0.2,timerSignificantDigits:int=3):"""_summary_ Parameters ---------- discardedPortion : float, optional discarded portion on the output , by default 0.2 (20%) timerSignificantDigits : int, optional Number of digits to use for the times printed, by default 3 """self.pr=cProfile.Profile()self.s=io.StringIO()self.ps=Noneself.discardedPortion=discardedPortionself.timerSignificantDigits=timerSignificantDigitsself.totTimes=Noneself.cumTimes=Noneself.sumTotTime=Noneself.sumCumTime=None
[docs]defStart(self)->None:"""Start the profiling """self.pr.enable()
[docs]defStop(self)->None:"""Stop the profiling """self.pr.disable()self.ps=pstats.Stats(self.pr,stream=self.s).sort_stats('cumulative')self.ps.reverse_order()self.ps.print_stats()lines=self.s.getvalue().split('\n')[5:-3]functionNames=[l[46:][-60:]forlinlines]parsing=np.array([l.split()[:5]forlinlines])totalTimes=np.array(parsing[:,1],dtype=float)cumulatedTimes=np.array(parsing[:,3],dtype=float)self.sumTotTime=np.sum(totalTimes)self.sumCumTime=np.sum(cumulatedTimes)totalTimes=totalTimes/np.sum(totalTimes)cumulatedTimes=cumulatedTimes/np.sum(cumulatedTimes)totalTimesArgSort=np.argsort(totalTimes)cumulatedTimesArgSort=np.argsort(cumulatedTimes)cumulatedSumTotalTimes=np.cumsum(totalTimes[totalTimesArgSort])cumulatedSumCumulatedTimes=np.cumsum(cumulatedTimes[cumulatedTimesArgSort])totalTimesArgSortInv=totalTimesArgSort[BinarySearch(cumulatedSumTotalTimes,self.discardedPortion)+1:][::-1]cumTimesArgSortInv=cumulatedTimesArgSort[BinarySearch(cumulatedSumCumulatedTimes,self.discardedPortion)+1:][::-1]totalTimes=totalTimes[totalTimesArgSortInv]totalTimes=np.hstack((totalTimes,1-np.sum(totalTimes)))cumulatedTimes=cumulatedTimes[cumTimesArgSortInv]cumulatedTimes=np.hstack((cumulatedTimes,1-np.sum(cumulatedTimes)))functionNamesTotalTime=[functionNames[i]foriintotalTimesArgSortInv]+["REMAINING"]functionNamesCumTime=[functionNames[i]foriincumTimesArgSortInv]+["REMAINING"]self.totTimes=OrderedDict(zip(totalTimes,functionNamesTotalTime))self.cumTimes=OrderedDict(zip(cumulatedTimes,functionNamesCumTime))
def__str__(self)->str:"""Return a string with all the collected information Returns ------- str Teh description """fromMuscat.Helpers.TextFormatHelperimportTFormatstring=TFormat.InBlue("Profiler")+" discarding "string+=str(int(100.*self.discardedPortion))+"% of the smallest functions\n"string+=TFormat.InRed("Total times:\n")forpart,nameinself.totTimes.items():string+=TFormat.InGreen(TFormat.Center(name,width=70))+": "+str(round(100.*part,2))string+="% ("+str(round(self.sumTotTime*part,self.timerSignificantDigits))+"s)\n"string+=TFormat.InRed("Cumulated times:\n")forpart,nameinself.cumTimes.items():string+=TFormat.InGreen(TFormat.Center(name,width=70))+": "+str(round(100.*part,2))string+="% ("+str(round(self.sumCumTime*part,self.timerSignificantDigits))+"s)\n"returnstring