Python常用的性能分析(Profiling)方法

本文以一个通过采样求圆周率pi的脚本,介绍一些常用的对Python脚本进行性能分析的方法,针对cpu-bound的问题,找到限制执行速度的瓶颈,为下一步的代码优化做准备

  • 最简单但是无法得到代码细节信息的方法
    • 在IPython中使用%timeit进行计时
      在这里插入图片描述
    • 在脚本中使用time模块或者计时功能的装饰器
# 使用time模块
import numpy as np
import time

def estimate_pi(n_estimator):
    count = 0
    for i in range(n_estimator):
        x = np.random.rand()
        y = np.random.rand()
        if x**2 + y**2 <= 1:
            count += 1
    return count / n_estimator

start_t = time.time()
pi = estimate_pi(1000000)
end_t = time.time()

print('time cost : %f'%(end_t - start_t))
# 使用装饰器
import numpy as np
import time

def time_wrapper(fn):
	def inner(*args, **kwargs):
		start_t = time.time()
		result = fn(*args, **kwargs)
		end_t = time.time()
		print('time cost : %f'%(end_t - start_t))
		return result
	return inner

@time_wrapper
def estimate_pi(n_estimator):
    count = 0
    for i in range(n_estimator):
        x = np.random.rand()
        y = np.random.rand()
        if x**2 + y**2 <= 1:
            count += 1
    return count / n_estimator

pi = estimate_pi(1000000)
  • 使用IPython %run -p 的命令得到运行过程中每一个函数的耗时
# 对pi值进行估计
# test.py
import numpy as np
def estimate_pi(n_estimator):
    count = 0
    for i in range(n_estimator):
        x = np.random.rand()
        y = np.random.rand()
        if x**2 + y**2 <= 1:
            count += 1
    return count / n_estimator

if __name__ == '__main__':
	pi = estimate_pi(1000000)
# IPython
%run -p test.py 

得到如下结果
在这里插入图片描述
说明estimate_pi这个函数的调用一共用了3.07s,其中1.265s花费在numpy的rand函数的调用上,剩下1.805s是花费在其他一些类似循环中的数值计算上面

  • 使用IPython %prun 的命令也可以得到运行过程中每一个函数的耗时,但是和%run -p 不同的是,%prun后面直接接命令,%run -p后面接脚本
# IPython
# -l 3 表示只显示前3行的
# 也可以加上 -s 的选项对结果按照指定的选项进行排序输出
%prun -l 3 estimate_pi(1000000)

在这里插入图片描述

  • 也可以在cmd中使用如下命令得到与%prun和%run相似的结果
# cmd
# 也可以加上一些 -s 的选项对输出结果进行定制
python -m cProfile test.py

上面的方法是对每个函数的耗时进行分析,下面介绍一种对函数中每行代码的耗时进行分析的方法,所以建议先进行每个函数的耗时分析,然后针对性的逐行分析

  • 使用line_profiler工具,windows下安装建议下载.whl进行安装,在想要分析的函数的定义处,加上@profile装饰器
# 对pi值进行估计
import numpy as np

@profile
def estimate_pi(n_estimator):
    count = 0
    for i in range(n_estimator):
        x = np.random.rand()
        y = np.random.rand()
        if x**2 + y**2 <= 1:
            count += 1
    return count / n_estimator

if __name__ == '__main__':
	pi = estimate_pi(1000000)
# cmd
kernprof -l -v test.py

可以得到该函数中某一行代码的耗时情况以及执行次数,如下图所示
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值