当我运行此代码时:
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 ms
6865.22507668 ms
分别。但是当我不打印值时,用print x
替换a = x
行,我得到相同的输出,
0.00119209289551毫秒
对于两者而言,虽然他们采取明显不同的时间这是为什么?
答案 0 :(得分:1)
当你不打印时,它非常快。 0.00119209289551 ms是time.time()可以捕获的最小'tick'。
因此报告均为0.00119209289551 ms。
准确估计速度。计算超过100,000个循环并比较总时间。
现在,如果似乎需要更长时间,例如,如果你自己计算时间,那么这就是可能发生的事情:
Python正在看到值2 ** 1000000并且说“嘿,那不是使用变量或任何东西,所以我可以在代码'运行'之前预先计算它。”很多语言都会这样做,他们会将3 * 5这样的东西转换为15,因为,嘿,为什么不呢?不妨节省计算能力。
所以等待的时间是python在程序运行之前花费“预先计算”值的时间。未设置t0time,因为脚本尚未运行。我不是python专家,但这就是很多语言,无论是脚本还是编译的,都是如此。
答案 1 :(得分:1)
检查简单表达式花费多少时间的正确方法是使用timeit
。 IPython:
In [6]: %timeit 2**100000
100000000 loops, best of 3: 16.4 ns per loop
In [7]: %timeit 2**1000000
100000000 loops, best of 3: 16.4 ns per loop
In [8]: %timeit 2**100000000
100000000 loops, best of 3: 16.4 ns per loop
Compiler time: 0.64 s
注意所花费的时间是如何恒定的(16.4
纳秒。这是将任何常量加载到堆栈中所花费的时间)。但请注意最后一个语句如何显示Compiler time: 0.64s
。因此,正如已经观察到的那样,计算由编译器执行,而不是在运行时执行。在最后一个例子中,数字太大,编译时间很长,因此IPython也会显示它。
如果我们尝试更大的数字,您会发现编译时间是唯一发生重大变化的时间:
In [9]: %timeit 2**1000000000
100000000 loops, best of 3: 16.4 ns per loop
Compiler time: 8.62 s
我们可以另外确认正在发生的事情,直接查看编译器使用dis
模块生成的字节码:
In [10]: import dis
...: dis.dis(lambda: 2**100000)
...:
2 0 LOAD_CONST 3 (999002093014384507944032764330033590 ... MANY more digits ... 396223208402597025155304734389883109376)
3 RETURN_VALUE
正如您所看到的,代码不包含任何计算结果的BINARY_POWER
运算符。我们对timeit
所做的时间只是对LOAD_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
未优化,虽然它看起来完全等同于使用return 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
有大约30万个数字!打印后者需要花费大约10倍的时间来打印前者(并且您的时间做确认这一点!)。