Python timeit模块实战:timeit、repeat与Timer类性能测试详解
本文详细介绍Python标准库timeit模块的三种使用方式:timeit()函数、repeat()函数及Timer类。通过对比列表头部插入与尾部追加的执行耗时,演示如何设置stmt、setup、number等参数,帮助开发者准确评估代码片段或函数的运行效率。
timeit模块概述与导入方式
Python内置的timeit模块专门用于精确测量代码片段的执行耗时,无论是简单的变量赋值还是复杂函数的调用,均可通过该模块进行性能评估。
作为Python标准库的一部分,timeit模块无需额外安装,直接导入即可使用。推荐使用 `import timeit` 语句,这样可以访问模块内的 `timeit()` 函数、`repeat()` 函数以及 `Timer` 类。若采用 `from timeit import ...` 方式导入,受限于全局变量 `__all__` 的定义,仅能导入 `Timer` 类。
timeit模块的源码实现非常精简,总计仅300多行,核心功能即上述两个函数和一个类的实现,开发者可自行查阅源码以深入理解其机制。
接下来将实际演示如何使用timeit模块进行性能测试,示例场景为对比Python列表从头部插入数据与从尾部追加数据的执行时间差异,具体测试目标可根据实际需求调整。
使用timeit()函数测试运行时间
一、使用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执行所需的环境配置,包括导入的模块、使用的参数或变量等,例如 `setup = 'from __main__ import func'`。支持单行或多行语句,多行语句间使用分号分隔。
若未提供stmt和setup参数,测试将失去意义,因此这两个参数为必填项。
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()函数测试运行时间
二、使用repeat()函数测试运行时间
1. repeat(stmt="pass", setup="pass", timer=default_timer, repeat=default_repeat, number=default_number) 函数介绍
repeat()函数包含五个关键字参数,均设有默认值。相较于timeit()函数,repeat()函数保留了所有原有参数,并新增了一个repeat参数。
repeat:指定测试重复执行的次数,可理解为将相同参数的timeit()函数重复运行多次。最终结果以列表形式返回,默认值为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类测试运行时间
三、使用Timer类测试运行时间
1. Timer类介绍
前文使用的timeit()函数和repeat()函数,实际上是对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模块的实战应用,希望能为读者提供有益参考。如有任何疑问,欢迎留言交流,小编会及时回复。感谢大家对本站的支持! 若本文对您有帮助,欢迎转载,请注明出处,谢谢!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









