学 Python 的你不可能没有听说过一些编辑工具,如 Pycharm,VScode 等等,他们除了提供对代码的格式化,注释,跳转等便捷处理方式之外,还提供 debug 功能,不可谓不强大。
假如我们的测试环境是 AIX 操作系统的,或者是一些 Linux 系统上,但是没有也不能安装 Pycharm,VScode工具,那我们该如何调试,或者做性能分析叫?
这就是今天推荐的两大法宝:pdb 和 cProfile
一、调试工具 pdb
Python 的 pdb,是其自带的一个调试库。它为 Python 程序提供了交互式的源代码调试功能,是命令行版本的 IDE 断点调试器,完美地解决了不借助工具进行调试的问题。
a = 1
b = 2
import pdb
pdb.set_trace()
c = 3
print(a + b + c)
当我们运行这个程序时时,它的输出界面是下面这样的,表示程序已经运行到了
> /Users/jingxiao/test.py(5)<module>()
-> c = 3
此时表示代码即将准备运行 c = 3。
如果要执行下一句,直接输入 “n” 回车。
如果要打印变量名,则输入 “p 变量名” 再回车。
如果要跳转到函数内部执行,则输入 “s” 再回车,就是 step into 的意思。
如果要跳出函数内部,则输入"r" 再回车,就是 stop out 的意思。
如果要在某行设置断点,则输入 “b 断点行号” 再回车。
如果要一直运行到下一个断点,则输入 “c” 再回车。
更多使用帮助,请参考官方文档:
https://docs.python.org/3/library/pdb.html#module-pdb
二、性能分析工具 cProfile
Python 自带的 cprofile 库,可以对代码的每个部分进行动态的分析,比如准确计算出每个模块消耗的时间等。这样你就可以知道程序的瓶颈所在,从而对其进行修正或优化。当然,这并不需要你花费特别大的力气。
举个例子,以下代码如何分析哪一步耗时多?
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n-1) + fib(n-2)
def fib_seq(n):
res = []
if n > 0:
res.extend(fib_seq(n-1))
res.append(fib(n))
return res
print(fib_seq(30))
一种方法是这样运行:
import cProfile
# def fib(n)
# def fib_seq(n):
cProfile.run('fib_seq(30)')
另一种方法是这样运行:
python -m cProfile test.py
运行结果如下所示:
ncalls,是指相应代码 / 函数被调用的次数;
tottime,是指对应代码 / 函数总共执行所需要的时间(注意,并不包括它调用的其他代码 / 函数的执行时间);
percall,就是上述两者相除的结果,也就是 tottime / ncalls;
cumtime,则是指对应代码 / 函数总共执行所需要的时间,这里包括了它调用的其他代码 / 函数的执行时间;
cumtime percall,则是 cumtime 和 ncalls 相除的平均结果。
了解这些参数后,再来看这张图。我们可以清晰地看到,这段程序执行效率的瓶颈,在于函数 fib(),它被调用了 700 多万次。
有没有什么办法可以提高改进呢?答案是肯定的。通过观察,我们发现,程序中有很多对 fib() 的调用,其实是重复的,那我们就可以用字典来保存计算过的结果,防止重复。改进后的代码如下所示:
def memoize(f):
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
@memoize
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n-1) + fib(n-2)
def fib_seq(n):
res = []
if n > 0:
res.extend(fib_seq(n-1))
res.append(fib(n))
return res
fib_seq(30)
再次执行 cProfile 得到下面的结果:
可以看到性能有极大的提升。
这个简单的例子,便是 cProfile 的基本用法。当然,cProfile 还有很多其他功能,还可以结合 stats 类来使用,你可以阅读相应的官方文档。
三、购买 Python 课程
内容部分摘录自极客专栏《Python核心技术与实践》,想购买的话可以先看下我之前的文章,文末有返现活动 :
感受一下大神的力量
(完)
网友评论