当前位置: 首页 > 后端技术 > Python

使用timeit测试Python函数性能

时间:2023-03-26 12:42:46 Python

timeit是Python标准库内置的一个小工具,可以快速测试小段代码的性能。知道timeittimeit函数:timeit.timeit(stmt,setup,timer,number)参数说明:stmt:statement的缩写,你要测试的代码或语句,纯文本,默认值为“pass”setup:运行前的配置stmt语句,纯文本,默认值也是"pass")是timeit的repeat版本,可以指定重复timeit的次数,默认3次,然后返回一个数组。一个简单的例子来说明用法:importtimeitprint(timeit.timeit('output=10*5'))#0.014560436829924583print(timeit.repeat('output=10*5'))#[0.01492984383367002,0.013428774895146496,0.0138426,4648]488】嗯,看来没什么不妥。事实上,没有人会测试无意义的加减乘除。我们需要测试我们自己的代码。测试多行代码测试多行代码可以使用分号来连接语句。print(timeit.timeit(stmt='a=10;b=10;sum=a+b'))也可以用三引号来写stmt。importtimeitimport_module="importrandom"testcode='''deftest():returnrandom.randint(10,100)'''print(timeit.repeat(stmt=testcode,setup=import_module))但它实际上非常荒谬,自己的代码会这么简单?我们是模块化编程。测试模块中的函数如果要测试的函数都在一个模块中,可以这样写timeit。importtimeitimportrandomimportarrow#本地函数defstupid1():returnrandom.randint(1,10)#依赖其他函数defstupid2():returnstupid1()#依赖其他包或模块defstupid3():returnarrow.now()print(timeit.timeit('stupid1()',setup='from__main__importstupid1'))print(timeit.timeit('stupid2()',setup='from__main__importstupid2'))print(timeit.timeit('stupid3()',setup='from__main__importstupid3',number=100))这样写其实就是单行模式。可以借用default_timertimeit自带的default_timer。importtimeitimportrandomdeftest():returnrandom.randint(10,100)starttime=timeit.default_timer()print("开始时间是:",starttime)test()print("时差是:",timeit.default_timer()-starttime)命令行使用timeit也支持命令行的调用方式,不过感觉太累了,没必要尝试。C:\pythontest>python-mtimeit-s'text="helloworld"'20000000loops,bestof5:13.1nsecperloop分享一个2月29日的案例,我觉得今年是闰年,有几种方法计算闰年的算法?孔乙己说有3种:defis_leap_year_0(year):ifyear%4==0:ifyear%100==0:ifyear%400==0:returnTrueelse:returnFalseelse:returnTrueelse:returnFalsedefis_leap_year_1(year):returnyear%4==0and(year%100!=0oryear%400==0)defis_leap_year_2(year):如果year%400==0:returnTrueifyear%100==0:returnFalseifyear%4==0:returnTruereturnFalse这三种方法哪个最好?这不能一概而论,因为它取决于你的参数是什么。例如,1991年不是闰年。方法0和方法1直接返回,方法2需要到最后的if才能知道不是闰年。比如2020,方法2直接返回,但是方法0和1需要到最里面if才能得到结果。所以我们需要抽样测试才能公平。例如,从1900到2900,每个函数运行10,000次。timeit不是很方便,它接受的参数不能这么复杂,我们需要把它包裹起来。defperf_test(method):years=range(1900,2900)ifmethod==0:foryinyears:is_leap_year_0(y)ifmethod==1:foryinyears:is_leap_year_1(y)ifmethod==2:对于y年:is_leap_year_2(y)print(timeit('perf_test(0)',setup='from__main__importperf_test',number=10000))print(timeit('perf_test(1)',setup='from__main__importperf_test',number=10000))print(timeit('perf_test(2)',setup='from__main__importperf_test',number=10000))猜猜哪种方法的结果最好?你千万别想。1.64327802509069441.75272723706439140.0023122059646993876其他思路timeit其实太弱了,随便测试一下还好,如果真要查性能问题,就需要用更专业的手段了。例如:PyCharmProfiler(Pro版功能)cProfilepycallgraphmemory_profiler下次有机会再说。作者简介:TobyQin,Python技术爱好者,目前从事测试开发相关工作,转载请注明原始出处。欢迎关注我的博客https://tobyqin.cn,你可以去我的公众号做个吃瓜群众。