Python 使用time.time()时出现奇怪的计时问题
当我运行此代码时:Python 使用time.time()时出现奇怪的计时问题,python,time,timing,Python,Time,Timing,当我运行此代码时: t0time = time.time() print 2**100000 #hundred thousand t1time = time.time() print (t1time - t0time)*1000,"ms" t0time = time.time() print 2**1000000 #million t1time = time.time() print (t1time - t0time)*1000,"ms" 该代码: t0time = time
t0time = time.time()
print 2**100000 #hundred thousand
t1time = time.time()
print (t1time - t0time)*1000,"ms"
t0time = time.time()
print 2**1000000 #million
t1time = time.time()
print (t1time - t0time)*1000,"ms"
该代码:
t0time = time.time()
print 2**100000 #hundred thousand
t1time = time.time()
print (t1time - t0time)*1000,"ms"
t0time = time.time()
print 2**1000000 #million
t1time = time.time()
print (t1time - t0time)*1000,"ms"
他们输出
70.0349807739毫秒
6865.22507668毫秒
分别地但是当我不打印值时,用a=x
替换print x
行,我得到相同的输出,
0.00119209289551毫秒
对两者来说,虽然时间明显不同。为什么会这样?不打印时,打印速度非常快。0.00119209289551毫秒是time.time()能够捕捉到的最小“滴答声” 所以两者都报告0.00119209289551毫秒 以便准确估计速度。对它们进行100000次循环计时,并比较总次数 现在,若它看起来需要更长的时间,例如,若你们自己计算时间,那个么下面是可能发生的情况: Python看到值为2**1000000,并说“嘿,这不是在使用变量或任何东西,所以我可以在代码‘运行’之前预先计算它。”很多语言都会这样做,它们会将3*5转换为15,因为,嘿,为什么不呢?还不如节省计算能力
因此,您等待的时间就是python在程序运行之前“预计算”值的时间。未设置t0time,因为脚本尚未运行。我不是python专家,但很多语言(包括脚本语言和编译语言)都是这样做的。检查一个简单表达式需要多少时间的正确方法是使用。这在以下情况下尤其方便: 请注意所花费的时间是恒定的(
16.4
纳秒。这是将任何常数加载到堆栈中所花费的时间)。但是,请注意最后一条语句如何显示编译器时间:0.64s
。因此,正如已经观察到的,计算是由编译器执行的,而不是在运行时。在上一个示例中,这个数字非常大,以至于编译时间非常长,因此IPython也会显示它
如果我们尝试更大的数字,您会发现编译器时间是唯一发生显著变化的时间:
In [9]: %timeit 2**1000000000
100000000 loops, best of 3: 16.4 ns per loop
Compiler time: 8.62 s
我们可以通过直接查看编译器使用模块生成的字节码来确认发生了什么:
如您所见,代码不包含任何将计算结果的二进制幂
运算符。我们对timeit
所做的计时只是对LOAD\u CONST
操作进行计时,这需要相同的时间,与数字的大小无关
如果我们试图反汇编一个使用参数的程序,我们在运行时确实会得到计算结果:
In [12]: dis.dis(lambda x: x**2)
1 0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (2)
6 BINARY_POWER
7 RETURN_VALUE
此优化由窥视孔优化器执行,仅适用于常量。甚至代码也简单地表示为:
In [13]: def function():
...: a = 2
...: return a ** 100000
未进行优化,尽管它似乎完全等同于使用返回2**100000
:
In [14]: dis.dis(function)
2 0 LOAD_CONST 1 (2)
3 STORE_FAST 0 (a)
3 6 LOAD_FAST 0 (a)
9 LOAD_CONST 2 (100000)
12 BINARY_POWER
13 RETURN_VALUE
还要注意,打印一个数字所需的时间与其大小成正比<代码>2**100000约有30k位,而
2**1000000
约有300k位!打印后者所需的时间大约是打印前者所需时间的10倍(您的计时确实证实了这一点!)。但在不打印的情况下,a=21000000比a=2100000所需的时间更长。不,编译代码所需的时间更长,执行所需的时间相同。我将更新我的答案以进行解释。打印时所花费的大量时间是预编译服务器上的I/Oamount@user1188752这可能取决于python版本。也许旧版本没有将所有常量都折叠到字节码中。在python2.6+和python3+中,由于计算是在编译过程中执行的,因此所需的时间完全相同。2**100000
有30103
位,而2**1000000
有301030
位,即是第一个位数的十倍。你的时间安排证实了这一点。我不明白你为什么认为这很奇怪。什么?我认为这并不奇怪,这与我的问题无关:)好吧,这是有道理的。我对编译和其他方面不太了解,但非常感谢您的详细解释。