ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
![](https://img.kancloud.cn/41/e0/41e066af9a6c25a24868d9667253ec98_1241x333.jpg) ***** ## 调试和性能分析 ### 用 pdb 进行代码调试 首先,我们来看代码的调试。也许不少人会有疑问:代码调试?说白了不就是在程序中使用 print() 语句吗? <br>没错,在程序中相应的地方打印,的确是调试程序的一个常用手段,但这只适用于小型程序。因为你每次都得重新运行整个程序,或是一个完整的功能模块,才能看到打印出来的变量值。如果程序不大,每次运行都非常快,那么使用 print(),的确是很方便的。 <br>可能又有人会说,现在很多的 IDE 不都有内置的 debug 工具吗? ### 如何使用 pdb 首先,要启动 pdb 调试,我们只需要在程序中,加入`import pdb`和`pdb.set_trace()`这两行代码就行了 ~~~ a = 1 b = 2 import pdb pdb.set_trace() c = 3 print(a + b + c) ~~~ 这时,我们就可以执行,在 IDE 断点调试器中可以执行的一切操作,比如打印,语法是"p ": ~~~ (pdb) p a 1 (pdb) p b 2 ~~~ 除了打印,常见的操作还有“n”,表示继续执行代码到下一行 ~~~ (pdb) n -> print(a + b + c) ~~~ 而命令`l`,则表示列举出当前代码行上下的 11 行源代码,方便开发者熟悉当前断点周围的代码状态 ~~~ (pdb) l 1 a = 1 2 b = 2 3 import pdb 4 pdb.set_trace() 5 -> c = 3 6 print(a + b + c) ~~~ 命令“s“,就是 step into 的意思,即进入相对应的代码内部。 <br>当然,除了这些常用命令,还有许多其他的命令可以使用 参考对应的官方文档:[https://docs.python.org/3/library/pdb.html#module-pdb%EF%BC%89](https://docs.python.org/3/library/pdb.html#module-pdb%EF%BC%89) ## 用 cProfile 进行性能分析 关于调试的内容,我主要先讲这么多。事实上,除了要对程序进行调试,性能分析也是每个开发者的必备技能。 日常工作中,我们常常会遇到这样的问题:在线上,我发现产品的某个功能模块效率低下,延迟高,占用的资源多,但却不知道是哪里出了问题。 这时,对代码进行 profile 就显得异常重要了。 这里所谓的 profile,是指对代码的每个部分进行动态的分析,比如准确计算出每个模块消耗的时间等。 <br>计算斐波拉契数列,运用递归思想 ~~~ 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) ~~~ 接下来,我想要测试一下这段代码总的效率以及各个部分的效率 ~~~ import cProfile cProfile.run('fib_seq(30)') ~~~ ![](https://img.kancloud.cn/2b/15/2b15939d6da0fd14d07e4c7c15fb3c49_1384x428.png) 参数介绍: * ncalls,是指相应代码 / 函数被调用的次数 * tottime,是指对应代码 / 函数总共执行所需要的时间(注意,并不包括它调用的其他代码 / 函数的执行时间) * tottime percall,就是上述两者相除的结果,也就是tottime / ncalls * cumtime,则是指对应代码 / 函数总共执行所需要的时间,这里包括了它调用的其他代码 / 函数的执行时间 * cumtime percall,则是 cumtime 和 ncalls 相除的平均结果。