Effective Python 读书笔记: 第58条: 先分析性能,然后再优化

# -*- encoding: utf-8 -*-

from bisect import bisect_left
from cProfile import Profile
from pstats import Stats
from random import randint

'''
第58条: 先分析性能,然后再优化

关键:
1 性能问题
建议: 优化程序之前先分析性能
性能分析工具: profiler,可以计算程序中某部分执行时间在总体时间中的占比
主要有: cProfile, profile
cProfile: c语言编写的profile,合理运行开销,推荐
profile: 纯python模块,本身占据时间,不推荐

2 cProfile模块
cProfile.Profile.run(comand, fileName=None, sort=-1)
作用: 该函数接收一个单独的参数,并可以被传递到exec()方法,并
添加一个可选的文件名称。

cProfile.Profile.runcall(func, *args, **kwargs)
作用: 通过runcall方法运行定义的函数func

3 pstats模块
pstats.Stats(*filename or profile, stream=sys.stdout)
作用: 

pstats.Stats.strip_dirs()
作用: 去除文件名前的路径信息,减少体积


pstats.Stats.sort_stats('cmulative')
作用: 最重要的函数,用来排序profile的输出

pstats.Stats.print_stats(*restrictions)
作用: 把Stats报表输出到stdout

pstatus.Stats.print_callers(*restrictions)
作用: 输出调用了指定的函数的函数相关信息

统计结果样例输出:
         20003 function calls in 1.312 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    1.312    1.312 /home/discovery/driver58.py:80(<lambda>)
        1    0.004    0.004    1.312    1.312 /home/discovery/driver58.py:62(insertSort)
    10000    1.289    0.000    1.308    0.000 /home/discovery/driver58.py:69(insertValue)
     9992    0.019    0.000    0.019    0.000 {method 'insert' of 'list' objects}
        8    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

解释:
ncalls: 函数在性能分析期间的调用次数
tottime: 执行该函数所花费的总秒数,本函数因调用其他函数所耗费的时间,不记入在内
tottime percall: 每次调用该函数所花的平均秒数, 本函数因调用其他
                函数所耗费的时间,不记入在内。此值等于totime与ncalls相除的商
cumtime:执行该函数及其中的全部函数调用操作,所花的总秒数
cumtime percall: 每次执行该函数及其中全部函数调用操作,所花费的平均秒数。
                此值等于cumtime与ncalls相除的商。

4 总结
性能分析时应该使用cProfile模块,调用该cProfile对象的runcall方法
来分析程序的性能,通过pstats.Stats对象来筛选处性能分析数据。


参考:
[1] Effectiv Python 编写高质量Python代码的59个有效方法
[2] https://blog.csdn.net/weixin_40304570/article/details/79459811
[3] https://docs.python.org/2.7/library/profile.html#module-cProfile
[4] https://docs.python.org/2.7/library/profile.html#module-pstats
[5] https://blog.csdn.net/u010453363/article/details/78415553?utm_source=blogxgwz9
'''

def insertSort(data):
    result = []
    for value in data:
        insertValue(result, value)
    return result


def insertValue(array, comparedValue):
    # for i, value in enumerate(array):
    #     if value > comparedValue:
    #         array.insert(i, comparedValue)
    #         return
    # array.append(comparedValue)
    i = bisect_left(array, comparedValue)
    array.insert(i, comparedValue)


def validInsertSort():
    maxValue = 10 ** 4
    data = [randint(0, maxValue) for _ in range(maxValue)]
    validProfile = lambda: insertSort(data)
    profiler = Profile()
    profiler.runcall(validProfile)
    stats = Stats(profiler)
    stats.sort_stats('cumulative')
    stats.print_callers()
    stats.print_stats()


def process():
    validInsertSort()


if __name__ == "__main__":
    process() 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值