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实现文件复制删除
Apr 19 Python
Python获取SQLite查询结果表列名的方法
Jun 21 Python
Python模块搜索路径代码详解
Jan 29 Python
python+opencv实现阈值分割
Dec 26 Python
Django实现学员管理系统
Feb 26 Python
python+selenium实现简历自动刷新的示例代码
May 20 Python
Python使用ffmpy将amr格式的音频转化为mp3格式的例子
Aug 08 Python
django-rest-swagger对API接口注释的方法
Aug 29 Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
Feb 26 Python
Python通过Pillow实现图片对比
Apr 29 Python
如何使用python自带IDLE的几种方法
Oct 10 Python
Python可视化学习之matplotlib内置单颜色
Feb 24 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
Oracle 常见问题解答
2006/10/09 PHP
php class中self,parent,this的区别以及实例介绍
2013/04/24 PHP
php加密算法之实现可逆加密算法和解密分享
2014/01/21 PHP
PHP list() 将数组中的值赋给变量的简单实例
2016/06/13 PHP
微信支付开发动态链接Native支付
2016/07/12 PHP
php中get_magic_quotes_gpc()函数说明
2017/02/06 PHP
PHP日期和时间函数的使用示例详解
2020/08/06 PHP
JavaScript 加号(+)运算符号
2009/12/06 Javascript
两个JavaScript jsFiddle JSBin在线调试器
2010/03/14 Javascript
javascript跑马灯悬停放大效果实现代码
2012/12/12 Javascript
jquery中focus()函数实现当对象获得焦点后自动把光标移到内容最后
2013/09/29 Javascript
浅谈javascript回调函数
2014/12/07 Javascript
javascript实现了照片拖拽点击置顶的照片墙代码
2015/04/03 Javascript
微信企业号开发之微信考勤百度地图定位
2015/09/11 Javascript
利用jQuery及AJAX技术定时更新GridView的某一列数据
2015/12/04 Javascript
jQuery遮罩层实现方法实例详解(附遮罩层插件)
2015/12/08 Javascript
js前端解决跨域问题的8种方案(最新最全)
2016/11/18 Javascript
Node.js环境下Koa2添加travis ci持续集成工具的方法
2017/06/19 Javascript
JavaScript实现带有子菜单和控件的slider轮播图效果
2017/11/01 Javascript
vue.js引入外部CSS样式和外部JS文件的方法
2019/01/06 Javascript
jQuery实现消息弹出框效果
2019/12/10 jQuery
JavaScript canvas绘制折线图
2020/02/18 Javascript
解决vue axios跨域 Request Method: OPTIONS问题(预检请求)
2020/08/14 Javascript
[04:55]完美世界副总裁蔡玮:DOTA2的自由、公平与信任
2013/12/18 DOTA
[05:41]2014DOTA2西雅图国际邀请赛 小组赛7月10日TOPPLAY
2014/07/10 DOTA
[02:03]永远的信仰DOTA2 中国军团历届国际邀请赛回顾
2016/06/26 DOTA
Python自动化运维_文件内容差异对比分析
2017/12/13 Python
pandas 对日期类型数据的处理方法详解
2019/08/08 Python
python中delattr删除对象方法的代码分析
2020/12/15 Python
优秀语文教师事迹
2014/05/18 职场文书
安全负责人任命书
2014/06/06 职场文书
无房产证房屋转让协议书合同样本
2014/10/18 职场文书
房产证明范本
2015/06/19 职场文书
清明扫墓感想
2015/08/11 职场文书
研究生毕业登记表的自我鉴定范文
2019/07/15 职场文书
Apache POI操作批量导入MySQL数据库
2022/06/21 Servers