python timeit函数是否可能报告0作为执行时间?
我正在从事一个项目,在该项目中,我们必须比较大小为2到2^16的列表的几种排序算法(插入排序、快速排序、合并排序等)的执行时间。我的指导老师指出,由于现代计算机速度非常快,“小”尺寸的运行时可能根本不会注册,并报告为0。作为一种解决方案,建议对于小实例,我们在一个额外的循环中运行该算法,并计算总执行时间,然后将该总时间除以循环重复次数。比如说,python timeit函数是否可能报告0作为执行时间?,python,algorithm,insertion-sort,timeit,Python,Algorithm,Insertion Sort,Timeit,我正在从事一个项目,在该项目中,我们必须比较大小为2到2^16的列表的几种排序算法(插入排序、快速排序、合并排序等)的执行时间。我的指导老师指出,由于现代计算机速度非常快,“小”尺寸的运行时可能根本不会注册,并报告为0。作为一种解决方案,建议对于小实例,我们在一个额外的循环中运行该算法,并计算总执行时间,然后将该总时间除以循环重复次数。比如说, while(repeat test 20 times) while(execute algorithm 50 times)
while(repeat test 20 times)
while(execute algorithm 50 times)
run algorithm
我使用Python的timeit函数来实现这一点,如下所示
setup = '''
gc.enable()
import random
from __main__ import insertionSort
from __main__ import n #current instance size
from __main__ import s #random array
'''
average = sum(timeit.Timer('A=s[:]; insertionSort(A);',setup = setup).repeat(20,50))/20
我对n到32的大小执行此操作,在这一点上,我继续通过
average = sum(timeit.Timer('A=s[:]; insertionSort(A);',setup = setup).repeat(1,50))/50
我遇到的问题是,一旦我超过32,平均值就会下降
Averages for size 2^ 1
Insertion Sort Average: 0.00014180380003381288
Averages for size 2^ 2
Insertion Sort Average: 0.0002706763001697254
Averages for size 2^ 3
Insertion Sort Average: 0.0005087433502012573
Averages for size 2^ 4
Insertion Sort Average: 0.0018256775000736526
Averages for size 2^ 5
Insertion Sort Average: 0.006701907949900487
Averages for size 2^ 6
Insertion Sort Average: 0.00045550270002422624 #smaller average for larger instance?!
所以我想我的问题是-是否需要额外重复较小的实例?我尝试对大小为2的单次执行进行计时,得到的数字非常接近0(x10^-6),但实际上从未得到零 我尝试了一些实验,这似乎是必要的——不是为了避免0次,而是为了分摊一些开销。这是一个典型的示例,pass命令的退化情况:
>>> for n in range(9):
... timeit.timeit("pass", number=10**n)/(10**n)
...
3.0994415283203125e-06
1.9073486328125001e-07
5.0067901611328123e-08
3.6001205444335936e-08
3.3092498779296877e-08
3.4611225128173827e-08
1.6702890396118163e-08
1.2709689140319825e-08
1.1296820640563965e-08
这表明开销约为3微秒,执行时间约为11纳秒。默认情况下,大多数
timeit
函数运行代码1000000次。这就是为什么不需要额外的循环。顺便说一句,你在repeat()
调用中用50
重写了它,只循环了50次。是的,我只运行了50次执行,因为对于n的巨大值,执行每个算法需要大量的时间。这就是为什么我要问我是否应该为较小的实例执行额外的循环,也因为它实际上似乎从来都不是0。做一个实验:在循环中运行print(time.time())
几次。看看你是否能得到完全相同的时间。否则,即使测量正时也会导致数值>0。