为什么程序执行的时间每次都不一样?

Why is the time of program execution different every time?

为什么我每次为 t1_perf_time 和 t1_timeit_time 执行以下程序时都会得到不同的时间?为什么每次执行的时间不一样?

import numpy as np
import time
import timeit

t0_process_time = time.process_time()
t0_perf_time = time.perf_counter()
t0_timeit = timeit.default_timer()

x = np.array([[[1, 2],
               [3, 4]],
              
              [[5, 6],
               [7, 8]], 
              
              [[3, 1],
               [1, 5]]])

x_min = np.amin(x, axis=0)
print(x_min)

print("t1_process_time: ", time.process_time() - t0_process_time)
print("t1_perf_time: ", time.perf_counter() - t0_perf_time)
print("t1_timeit_time: ", timeit.default_timer() - t0_timeit)

结果如下:

  1. 程序的执行: t1_process_time:0.0; t1_perf_time:0.0008847999852150679; t1_timeit_time: 0.0009033000096678734

  2. 程序的执行: t1_process_time:0.0; t1_perf_time:0.0003133999998681247; t1_timeit_time: 0.0003309999592602253

  3. 程序的执行: t1_process_time:0.0; t1_perf_time:0.000278300023637712; t1_timeit_time: 0.0003150000120513141

这可能取决于系统资源的可用性,尤其是与其他进程共享的资源。如果没有您系统状态的完整快照,我们无法真正判断。然而,这就是为什么我们不测量程序的个别 运行 的原因:系统中有太多混杂变量。如果您想对 运行 时间进行良好的分析,请在 timeit 中使用重复因子,并 运行 来自脚本的程序。

因为这就是一切的运作方式:您的电脑将始终以不同的方式忙碌,现在它正在处理浏览器,现在它正在检查病毒,现在电池电量比以前低,等等,等等,导致程序以不同的速度运行。

timeit 不是给你 确切的 处理时间,因为没有这样的东西。相反,它让您全面了解代码的运行速度,或者比较同一概念的两个不同实现,以便您可以选择在大多数 运行 上最快的实现。

时间增量很小,但由于这些数字很小,所以看起来很大。但我认为主要问题是你主要测量打印东西需要多长时间,其中包括对系统的调用,每个 运行 会有很大差异。将结束时间调用移动到打印件上方可提供更一致的结果。

import numpy as np
import time
import timeit

t0_process_time = time.process_time()
t0_perf_time = time.perf_counter()
t0_timeit = timeit.default_timer()

x = np.array([[[1, 2],
               [3, 4]],
              
              [[5, 6],
               [7, 8]], 
              
              [[3, 1],
               [1, 5]]])

x_min = np.amin(x, axis=0)


t1_process_time = time.process_time()
t1_perf_time =  time.perf_counter()
t1_timeit_time = timeit.default_timer()

#print(x_min)
print("----------")
print("t1_process_time: ", t1_process_time - t0_process_time)
print("t1_perf_time: ", t1_perf_time - t0_perf_time)
print("t1_timeit_time: ", t1_timeit_time - t0_timeit)

还有几个运行s

~/tmp/aaa$ python3 test.py
----------
t1_process_time:  4.363200000001566e-05
t1_perf_time:  4.216799970890861e-05
t1_timeit_time:  4.1728000724106096e-05
~/tmp/aaa$ python3 test.py
----------
t1_process_time:  4.598000000000102e-05
t1_perf_time:  4.489000093599316e-05
t1_timeit_time:  4.4754000555258244e-05
~/tmp/aaa$ python3 test.py
----------
t1_process_time:  4.239400000000115e-05
t1_perf_time:  4.161900142207742e-05
t1_timeit_time:  4.158100091444794e-05
~/tmp/aaa$ python3 test.py
----------
t1_process_time:  4.783699999999502e-05
t1_perf_time:  4.641800114768557e-05
t1_timeit_time:  4.633000025933143e-05
~/tmp/aaa$ python3 test.py
----------
t1_process_time:  4.620399999999414e-05
t1_perf_time:  4.536599954008125e-05
t1_timeit_time:  4.5202999899629503e-05
~/tmp/aaa$ python3 test.py
----------
t1_process_time:  4.341699999999005e-05
t1_perf_time:  4.237100074533373e-05
t1_timeit_time:  4.228999932820443e-05

最终,您程序中的代码执行的每个操作都可以简化为由逻辑门执行的更简单的布尔操作,逻辑门通过尺寸小于微观尺度的电子晶体管组合在硬件中实现。这些晶体管是电流被操纵以对应于二进制的地方。

虽然您可能期望计算机的数学运算总是花费相同的时间来计算,但实际上数学运算依赖于不太确定的物理世界,其中晶体管等事物的属性位于给定的可接受范围内误差,因为真正精确的值实际上是不可能设计的,因为诸如金属中的小杂质和切割尺寸的微小变化等因素。电本身的特性也可以在可接受的范围内变化。随着时间的推移,计算机的晶体管也会变热并发生变化甚至损坏。即使是来自 space 的电子量子隧穿和宇宙射线等现象也会对您计算机的性能产生细微影响。

宇宙本质上是混乱的,因此计算机本质上会受到这种混乱的影响。虽然计算机设计为尽可能少受到影响,但它们仍然会受到影响。