在编程实践中,经常需要测量代码的执行时间以评估性能。通常,人们会使用简单的时间测量方法,例如使用Python的time.time()
函数。但是,这种方法在测量非常小的代码片段时不够准确,因为它会受到操作系统中其他进程和任务的干扰。为了解决这个问题,Python提供了一个名为timeit
的模块,它专门用于测量小到大的代码片段的执行时间。本文将通过一些示例介绍如何在Python中使用timeit
模块。
timeit
模块提供了一个简单的方法来测量Python代码片段的执行时间。它既有命令行界面,也有可调用的接口。这个模块避免了测量执行时间时的一些常见陷阱。timeit
模块中的timeit.timeit()
函数是核心,它接受四个参数:stmt
(要测量执行时间的代码片段)、setup
(在执行stmt
之前运行的代码,通常用于导入模块或声明必要的变量)、timer
(默认的timeit.Timer
对象,通常不需要干预)、number
(指定stmt
执行的次数)。该函数返回执行stmt
指定次数所需的时间(以秒为单位)。
下面是一个使用timeit.timeit()
函数的示例,它测量了一个数学计算的执行时间。
import timeit
setup_code = "from math import sqrt"
stmt_code = "sum(sqrt(x) for x in range(1,10000))"
iterations = 10000
time = timeit.timeit(stmt=stmt_code, setup=setup_code, number=iterations)
print(time)
上述代码将代码作为字符串传递给timeit.timeit()
函数,并指定了迭代次数。输出是执行代码片段10000次所需的总时间,而不是单次迭代的时间。
接下来,使用timeit
模块比较两个排序函数的性能:一个简单的冒泡排序和一个Python内置的sorted()
函数。还将看到另一个timeit
函数repeat()
的使用。
def bubble_sort(arr):
for i in range(len(arr)):
for j in range(0, len(arr) - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
def make_random_array():
from random import randint
return [randint(-100, 100) for i in range(20)]
test_array = make_random_array()
def compare_functions():
import timeit
setup_code1 = """
from __main__ import bubble_sort
from __main__ import test_array
"""
setup_code2 = """
from __main__ import test_array
"""
stmt_code1 = "bubble_sort(test_array)"
stmt_code2 = "sorted(test_array)"
times1 = timeit.repeat(stmt=stmt_code1, setup=setup_code1, number=10000, repeat=5)
times2 = timeit.repeat(stmt=stmt_code2, setup=setup_code2, number=10000, repeat=5)
print(f"Time taken by bubble sort is {min(times1)}")
print(f"Time taken by built in sort is {min(times2)}")
if __name__ == "__main__":
compare_functions()
在这个例子中,确保两个函数在同一个数组上进行测试。timeit.repeat()
函数接受一个额外的参数repeat
(默认值为5),它返回一个执行时间列表,表示代码片段重复执行多次的结果。如预期,冒泡排序所需的时间远大于内置的sorted()
函数。
python -m timeit [-n N] [-r N] [-u U] [-s S][statement ...]
$ python -m timeit -s 'text = "sample string"; char = "g"' 'char in text'
5000000 loops, best of 5: 0.0877 usec per loop
$ python -m timeit -s 'text = "sample string"; char = "g"' 'text.find(char)'
1000000 loops, best of 5: 0.342 usec per loop