
【问题描述】
自然对数底数e=2.7182818284590…是科学和工程中经常使用的一个无理数,其计算公式为e=+…。请对求自然对数底数的程序进行分析,找出最花时间的操作,并对其进行优化。
运行结果:
备注:本次程序执行共调用函数1004次,耗时0.155秒。ncalls表示调用次数,tottime表示所有函数调用的总执行时间(不含函数内调用其他函数的时间),percall表示每次函数调用的时间percall=tottime/ncalls,cumtime表示累计调用时间(含函数内调用其他函数的时间),percall=cumtime/ncalls,filename:lineno(function)表示函数调用所在的文件及行号。
【程序代码】
【结果分析】
从运行结果可以看出,整个程序运行的瓶颈是factorial( )函数的调用,调用次数多,运行时间也最长。为此,如果要优化程序的运行时间可以从这个函数调用入手。
factorial( )函数是求阶乘的函数,由于Python是解释型语言,所以循环程序执行效率不高,而它提供的内置模块的函数却是C语言编写的,可以提高程序的运行效率,于是将factorial替换成math.factorial再次运行cProfile,我们可以对比一下执行效果。修改后的程序如下:
从执行结果看,因为修改一个函数调用,程序的运行速度比原来快了4倍。
此处仅是为了演示cProfile给大家举的一个简单的例子,如果不调用函数直接求e,执行速度会更快,这个算法的实现留给读者自己思考。
【优化提升】和timeit模块一样,cProfile模块也提供了命令行界面,可以通过在PyCharm窗口底部的Terminal面板中输入命令得到上述类似的分析结果。命令行为:python-m cProfile被检测的Python文件名,因为结果冗长,此处不显示,读者可自行输入该命令查看。
【技术全貌】
cProfile模块除了run函数外,还有其他函数可以用来检查程序的性能问题,见表11-3-3。如果要了解cProfile更详细的信息请扫描二维码查看官网文档。
表11-3-3 cProfile模块的函数