[Python--]Python Profilers 性能分析

来源:互联网 发布:unity3d中国官网 编辑:程序博客网 时间:2024/06/01 19:36

本来计划使用profile模块进行性能分析作为博客的第二篇记录,然而距上次使用profile也已经距离很长一段时间, 回忆整理起来还是比较麻烦,一个字,太懒了,恩。

之前测代码的运行时间一直使用的是timeit模块,后来才发现还有一个更强大的性能分析工具profile和cprofile,尤其是在你不知道具体哪段代码存在性能问题的时候。


profile很容易入手,在需要测试的代码内加入下面几行,就可以查看到底是哪块代码影响的性能

import cProfile, pstatspr = cProfile.Profile()pr.enable()# ... do something ...pr.disable()ps = pstats.Stats(pr).sort_stats('time')//按照时间排序ps.print_stats()


终于找到罪魁祸首了,大部分时间被strptime和parseMinute这两个函数耗费掉了(如果查看parseMinute代码会发现其也是由strptime实现的)。

def parseMinute(dt, minutesdelta):   """ minutesdelta measured in minutes   """   try:   dt = dt.strptime(dt, '%Y-%m-%d %H:%M:%S')       seconds = dt.minute * 60 + dt.second       secondsdelta = minutesdelta * 60       delta = math.ceil(seconds/secondsdelta)*secondsdelta - seconds       return datetime(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)\           + timedelta(seconds = delta)   except Exception, ex:       logger.error("%s" %  traceback.format_exc())       return None

看来问题就在于stptime上了。Python中datetime,time等类型都有strptime方法,将时间字符串根据格式解析成相应的对象。很多时候我们的需求只是解析”%Y-%m-%d %H:%M:%S”格式的字符串,而strptime会根据locale作相应不同的处理,增加了不必要的复杂度,造成性能瓶颈。当然早有前人发现了这个问题,也给出了解决办法。

【方法1】正则表达式

def parseMinute(dt, minutesdelta):    """ minutesdelta measured in minutes    """    try:        rep = re.compile(r'(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})')        dt = rep.match(dt)        year, month, day, hour, minute, second = \         int(dt.group(1)), int(dt.group(2)), int(dt.group(3)), int(dt.group(4)), int(dt.group(5)), int(dt.group(6))        seconds = minute * 60 + second        secondsdelta = minutesdelta * 60        delta = math.ceil(seconds/secondsdelta)*secondsdelta - seconds        return datetime(int(year), int(month), int(day), hour, minute, second)\            + timedelta(seconds = delta)    except Exception, ex:        logger.error("%s" %  traceback.format_exc())        return None



【方法2】字符串分隔

def parseMinute(dt, minutesdelta):   """ minutesdelta measured in minutes   """   try:       date, time = dt.split()       year, month, day = date.split('-')       hour, minute, second = time.split(':')       hour, minute, second = int(hour), int(minute), int(second)       seconds = minute * 60 + second       secondsdelta = minutesdelta * 60       delta = math.ceil(seconds/secondsdelta)*secondsdelta - seconds       return datetime(int(year), int(month), int(day), hour, minute, second)\           + timedelta(seconds = delta)   except Exception, ex:       logger.error("%s" %  traceback.format_exc())       return None


差距还是很容易看的见的。


0 0
原创粉丝点击