为什么函数的执行时间不恒定?

时间:2018-06-12 16:06:27

标签: python execution-time

我从理论上讲我的大学课程的功能增长顺序,并尝试在家实际实施。尽管增长的顺序与教科书完全相同,但它们的执行时间随着我执行程序的每一次而变化。那是为什么?

源代码

import time
import math
from tabulate import tabulate
n=eval(input("Enter the value of n: "));
t1=time.time()
a=12
t2=time.time()
A=t2-t1
t3=time.time()
b=n
t4=time.time()
B=t4-t3
t5=time.time()
c=math.log10(n);
t6=time.time()
C=t6-t5
t7=time.time()
d=n*math.log10(n);
t8=time.time()
D=t8-t7
t9=time.time()
e=n**2
t10=time.time()
E=t10-t9
t11=time.time()
f=2**n
t12=time.time()
F=t12-t11

print(tabulate([['constant',a,A], ['n',b,B], ['logn',c,C], ['nlogn',d,D], ['n**2',e,E], ['2**n',f,F]], headers=['Function', 'Value', 'Time']))
templist= [A,B,C,D,E,F]
print("The time order in acsending order is: ", sorted(templist,key=int)) 

首次执行

naufil@naufil-Inspiron-7559:~/Desktop/python$ python3 time_order.py
Enter the value of n: 100
Function              Value         Time
----------  ---------------  -----------
constant       12            2.14577e-06
n             100            1.43051e-06
logn            2            4.1008e-05
nlogn         200            3.57628e-06
n**2        10000            3.33786e-06
2**n            1.26765e+30  3.8147e-06
The time order in acsending order is:  [2.1457672119140625e-06, 1.430511474609375e-06, 4.100799560546875e-05, 3.5762786865234375e-06, 3.337860107421875e-06, 3.814697265625e-06]

第二次执行

naufil@naufil-Inspiron-7559:~/Desktop/python$ python3 time_order.py
Enter the value of n: 100
Function              Value         Time
----------  ---------------  -----------
constant       12            2.14577e-06
n             100            1.19209e-06
logn            2            4.64916e-05
nlogn         200            4.05312e-06
n**2        10000            3.33786e-06
2**n            1.26765e+30  3.57628e-06
The time order in acsending order is:  [2.1457672119140625e-06, 1.1920928955078125e-06, 4.649162292480469e-05, 4.0531158447265625e-06, 3.337860107421875e-06, 3.5762786865234375e-06]

2 个答案:

答案 0 :(得分:2)

正如其他评论和答案所正确指出的那样,您观察到的执行时间差异的原因来自操作系统的工作方式。但是采取严格的措施是一件很复杂的事情,所以让我详细说明一下,并指出你应该指导实验的地方。

您的操作系统背后的操作

您可以将操作系统视为指挥,并将程序视为乐器播放器,并且可以想象只有很多乐器可以同时播放。因此,指挥家必须每次都选择谁应该参加比赛,同时确保最终没有人感到沮丧!同样,操作系统因此总是负责选择要执行的程序,这意味着什么程序专用于CPU时间。可以同时执行的程序(或更确切地说是进程)的数量通常受处理器中核心数量的限制。

在实践中,操作系统选择执行什么的方式是一个非常复杂和迷人的主题,它依赖于实验支持的启发式方法。 (阅读更多here)。您必须了解的是,您几乎没有任何方法可以改变这种行为,也没有任何方法可以保证两次调用之间的执行时间相同。

使用linux' time命令

像你一样调用python' time来测量两次通话之间经过的实际时间,所以由于我们所说的,你不仅仅是衡量你在节目上花费的时间'执行。如果您想更好地了解操作系统实际专用于您的程序的时间,可以使用linux命令timeuser时间将为您提供专用于执行程序的实际CPU时间。查看this thread了解详情。但要明白,这一次也会受到震荡的影响!

你想从你的测量中得出什么智慧?

最后,您应该问问自己确切的时间是否真的符合您的要求。你关心价值吗?或者你想展示行为?

通常,衡量绩效的方法是平均重复呼叫的执行时间。这样,应该平衡与操作系统业务相关的影响。 (您可以将其视为构建随机过程的无偏估计)。根据我的理解,您试图显示具有不同复杂性的算法的执行时间差异。所以实际执行时间并不那么相关,相关的顺序是什么。这就是为什么平均多次调用会减少观察的方差,你可以对相对执行时间做出更强有力的陈述。

答案 1 :(得分:0)

您应该将此问题提交给您的操作系统。还有什么在你的电脑上运行?列出各种流程,看看有多少流程;所需要的只是一个进程甚至是一个上下文交换来改变你的执行时间。除此之外,调用time.time可以调用这样的开关,因为这是对系统进程的调用。

它还取决于您在调用它们时已经加载了哪些系统支持例程 - 其中许多调用是隐式或次要的。如果你需要为特定的指令分配更多的内存,因为另一个进程占用了你的最后一个RAM,然后换掉了......好吧,我希望你明白这个想法。