Python timeit模块的使用实践


Posted in Python onJanuary 13, 2020

Python 中的 timeit 模块可以用来测试一段代码的执行耗时,如一个变量赋值语句的执行时间,一个函数的运行时间等。

timeit 模块是 Python 标准库中的模块,无需安装,直接导入就可以使用。导入时直接 import timeit ,可以使用 timeit() 函数和 repeat() 函数,还有 Timer 类。使用 from timeit import ... 时,只能导入 Timer 类(有全局变量 __all__ 限制)。

timeit 模块的源码总共只有 300 多行,主要就是实现上面的两个函数和一个类,可以自己看一下。

接下来就开始使用 timeit 模块来测试代码执行时间,我使用 timeit 模块来对比 Python 列表从头部添加数据和从尾部添加数据的执行时间(测试什么根据需求来定)。

一、使用 timeit() 函数测试运行时间

1. 准备测试函数

先写两个函数,一个函数是从列表头部添加数据,另一个函数是从列表尾部添加数据。

# coding=utf-8
def insert_time_test():
  insert_list = list()
  for i in range(10):
    insert_list.insert(0, i)
def append_time_test():
  append_list = list()
  for i in range(10):
    append_list.append(i)
if __name__ == '__main__':
  import timeit

2. timeit(stmt="pass", setup="pass", timer=default_timer, number=default_number) 函数介绍

timeit() 函数有四个参数,每个参数都是关键字参数,都有默认值。

stmt:传入需要测试时间的代码,可以直接传入代码表达式或单个变量,也可以传入函数。传入函数时要在函数名后面加上小括号,让函数执行,如 stmt = ‘func()'  。

setup:传入 stmt 的运行环境,如 stmt 中使用到的参数、变量,要导入的模块等,如 setup = ‘from __main__ import func'。可以写一行语句,也可以写多行语句,写多行语句时用分号隔开。

如果 stmt 和参数 setup 参数不传值,那么就失去了测试的意义,所以这两个参数是必要的。

timer: timer 参数是当前操作系统的基本时间单位,默认会根据当前运行环境的操作系统自动获取(源码中已经定义),保持默认即可。

number:要测试的代码的运行次数,默认1000000(一百万)次,对于耗时的代码,运行太多次会花很多时间,可以自己修改运行次数。

3. 测试函数的运行时间

现在使用 timeit() 来测试上面两个函数的运行时间。

insert_time_timeit = timeit.timeit(stmt='insert_time_test()', 
                    setup='from __main__ import insert_time_test')
  print('insert_time_timeit: ', insert_time_timeit)
  append_time_timeit = timeit.timeit(stmt='append_time_test()', 
                    setup='from __main__ import append_time_test')
  print('append_time_timeit: ', append_time_timeit)

运行结果:

('insert_time_timeit: ', 2.9112871)
('append_time_timeit: ', 1.8884124999999998)

可以看到,在列表头部添加数据的时间比在列表尾部添加数据的时间长。

4. 测试代码(表达式)的运行时间

继续使用 timeit() 测试上面代码的运行时间,只是这次是直接将代码传入到参数中,而不是传入函数。

insert_time_timeit = timeit.timeit(stmt='list(insert_list.insert(0, i) for i in init_list)',
                    setup='insert_list=list();init_list=range(10)',
                    number=100000)
  print('insert_time_timeit: ', insert_time_timeit)
  append_time_timeit = timeit.timeit(stmt='list(append_list.append(i) for i in init_list)',
                    setup='append_list=list();init_list=range(10)',
                    number=100000)
  print('append_time_timeit: ', append_time_timeit)

由于时间很长,代码中特意将 number 从一百万次改成了十万次。运行结果如下:

('insert_time_timeit: ', 330.46189400000003)
('append_time_timeit: ', 0.21436310000001413)

相对来说,对于相同的操作,使用函数的运行时间远小于直接传入代码表达式的时间,头部插入数据的尤其明显。

二、使用 repeat() 函数测试运行时间

1. repeat(stmt="pass", setup="pass", timer=default_timer, repeat=default_repeat, number=default_number) 函数介绍

repeat() 函数有五个参数,每个参数都是关键字参数,都有默认值。相比 timeit() 函数而言,timeit() 函数有的参数 repeat() 函数都有,此外,repeat() 函数多了一个 repeat 参数。

repeat:表示测试要重复几次,可以理解为将相同参数的 timeit() 函数重复执行。最终的结果构成一个列表返回,repeat 默认为3次。

2. 测试函数的运行时间

现在使用 repeat() 来测试上面两个函数的运行时间。

insert_time_repeat = timeit.repeat(stmt='insert_time_test()',
                    setup='from __main__ import insert_time_test')
  print('insert_time_repeat: ', insert_time_repeat)
  append_time_repeat = timeit.repeat(stmt='append_time_test()',
                    setup='from __main__ import append_time_test')

  print('append_time_repeat: ', append_time_repeat)

运行结果如下:

('insert_time_repeat: ', [2.7707739, 2.908885, 2.7164823999999994])
('append_time_repeat: ', [1.7458063, 1.777368000000001, 1.8675014999999995])

3. 测试代码(表达式)的运行时间

继续使用 repeat() 测试上面代码的运行时间,直接传入代码,上面将 number 改成十万次后,时间还是很长(300多秒),所以继续减小 number ,改成一万次。

insert_time_repeat = timeit.repeat(stmt='list(insert_list.insert(0, i) for i in init_list)',
                    setup='insert_list=list();init_list=range(10)',
                    repeat=5,
                    number=10000)
  print('insert_time_repeat: ', insert_time_repeat)
  append_time_repeat = timeit.repeat(stmt='list(append_list.append(i) for i in init_list)',
                    setup='append_list=list();init_list=range(10)',
                    repeat=5,
                    number=10000)
  print('append_time_repeat: ', append_time_repeat)

运行结果如下:

('insert_time_repeat: ', [2.591015, 2.5814996999999997, 2.5547322, 2.6153070000000005, 2.5496864000000006])
('append_time_repeat: ', [0.0181692999999985, 0.01746889999999901, 0.018901899999999472, 0.018737400000000903, 0.018211900000000725])

三、使用 Timer 类测试运行时间

1. Timer 类介绍

上面使用了 timeit() 函数和 repeat() 函数,其实在 timeit 模块中,这两个函数都是对 Timer 类做了进一步的封装,实际调用的还是 Timer 类中的方法。

在 Timer 类中,实现了两个方法,timeit() 方法和 repeat() 方法,上面两个函数调用的就是这两个方法。

在使用  from timeit import ... 时,只能导入 Timer 类,所以可以直接使用 Timer 类来测试,可以自己去调用方法,使用起来更灵活。

2. 测试列表头部添加

先实例化一个 Timer 类的对象,实例化时传入 stmt 和 setup 参数(参数的含义与上面一致),timer 参数保持默认,然后通过实例对象调用对应的 timeit() 方法或 repeat() 方法,在 timeit() 方法中传入 number,在repeat() 方法中传入 number 和 repeat 。

使用 timeit() 方法和 repeat() 方法测试从头部添加数据的运行时间。

timer_insert = timeit.Timer(stmt='insert_time_test()', setup='from __main__ import insert_time_test')
  insert_time_timeit = timer_insert.timeit(number=1000000)
  print('insert_time_timeit: ', insert_time_timeit)
  insert_time_repeat = timer_insert.repeat(number=1000000)
  print('insert_time_repeat: ', insert_time_repeat)

运行结果如下:

('insert_time_timeit: ', 2.7732486)
('insert_time_repeat: ', [2.7367806999999997, 2.707402600000001, 2.7288245999999994])

3. 测试列表尾部添加

使用 timeit() 方法和 repeat() 方法测试从尾部添加数据的运行时间。

timer_append = timeit.Timer(stmt='append_time_test()', setup='from __main__ import append_time_test')
  append_time_timeit = timer_append.timeit(number=1000000)
  print('append_time_timeit: ', append_time_timeit)
  append_time_repeat = timer_append.repeat(number=1000000)
  print('append_time_repeat: ', append_time_repeat)

运行结果如下:

('append_time_timeit: ', 1.9966106000000001)
('append_time_repeat: ', [1.9523343999999998, 1.8373857999999998, 1.8695377000000004])

timeit 模块是一个比较简单的模块,大概用法就这些了。

总结

以上所述是小编给大家介绍的Python timeit模块的使用实践,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Python编程中实现迭代器的一些技巧小结
Jun 21 Python
Python实现对字符串的加密解密方法示例
Apr 29 Python
Tensorflow 查看变量的值方法
Jun 14 Python
python实现C4.5决策树算法
Aug 29 Python
python3 拼接字符串的7种方法
Sep 12 Python
OpenCV+Python识别车牌和字符分割的实现
Jan 31 Python
Python判断有效的数独算法示例
Feb 23 Python
python tkinter实现屏保程序
Jul 30 Python
Django 在iframe里跳转顶层url的例子
Aug 21 Python
keras实现基于孪生网络的图片相似度计算方式
Jun 11 Python
python基于tkinter制作m3u8视频下载工具
Apr 24 Python
python操作xlsx格式文件并读取
Jun 02 Python
Python 列表的清空方式
Jan 13 #Python
Python SSL证书验证问题解决方案
Jan 13 #Python
python清空命令行方式
Jan 13 #Python
Pytorch GPU显存充足却显示out of memory的解决方式
Jan 13 #Python
Python开发之基于模板匹配的信用卡数字识别功能
Jan 13 #Python
python中的itertools的使用详解
Jan 13 #Python
python3读取csv文件任意行列代码实例
Jan 13 #Python
You might like
社区(php&&mysql)一
2006/10/09 PHP
精通php的十大要点(上)
2009/02/04 PHP
php定时计划任务的实现方法详解
2013/06/06 PHP
php 利用array_slice函数获取随机数组或前几条数据
2015/09/30 PHP
Javascript 跨域访问解决方案
2009/02/14 Javascript
javascript 异常处理使用总结
2009/06/21 Javascript
Jquery 动态添加按钮实现代码
2010/05/06 Javascript
jquery maxlength使用说明
2011/09/09 Javascript
利用jQuery的deferred对象实现异步按顺序加载JS文件
2013/03/17 Javascript
JS实现鼠标单击与双击事件共存
2014/03/08 Javascript
解决jquery中动态新增的元素节点无法触发事件问题的两种方法
2015/10/30 Javascript
两行代码轻松搞定JavaScript日期验证
2016/08/03 Javascript
jQuery 生成svg矢量二维码
2016/08/09 Javascript
jQuery事件绑定用法详解
2016/09/08 Javascript
Vue插件写、用详解(附demo)
2017/03/20 Javascript
jQuery EasyUI 组件加上“清除”功能实例详解
2017/04/11 jQuery
vue2.0父子组件间通信的实现方法
2017/04/19 Javascript
js实现多张图片延迟加载效果
2017/07/17 Javascript
深入理解Vue 的条件渲染和列表渲染
2017/09/01 Javascript
vue 如何从单页应用改造成多页应用
2020/10/23 Javascript
python实现挑选出来100以内的质数
2015/03/24 Python
Python利用ElementTree模块处理XML的方法详解
2017/08/31 Python
OpenCV 模板匹配
2019/07/10 Python
python 求10个数的平均数实例
2019/12/16 Python
Cinque网上商店:德国服装品牌
2019/03/17 全球购物
机械工程师求职自我评价
2013/09/23 职场文书
酒店办公室文员岗位职责
2013/12/18 职场文书
护理工作感言
2014/01/16 职场文书
办理信用卡收入证明范例
2014/09/13 职场文书
法定代表人身份证明书(含说明)
2014/10/02 职场文书
2014年勤工助学工作总结
2014/11/24 职场文书
英语演讲开场白
2015/05/29 职场文书
母亲去世追悼词
2015/06/23 职场文书
学习党章心得体会2016
2016/01/15 职场文书
oracle数据库去除重复数据
2022/05/20 Oracle
vue如何清除浏览器历史栈
2022/05/25 Vue.js