我正在玩大数字,并写下以下代码:
import time
def ispow2(n):
return not n & n - 1
start = time.clock()
ispow2(2**100000000)
end = time.clock()
print(end - start)
令人惊讶的是,这会输出0.016864107385627148
,而且时间非常短。但是,它实际上需要8
秒,而不是0.02
。
为什么时间模块报告这么快的时间显然需要比运行代码更长的时间?
根据time
,clock()
已被弃用,因此我将其切换为process_time()
。我得到了几乎相同的结果。与perf_counter()
相同。
注意:这是从IDLE运行的。当我从命令行运行时,时间似乎准确报告。也许pythonw.exe与此有关,但是什么?
但是,当我在0
的末尾添加另一个2**10...
时,命令行需要约7秒,但报告0.1781140373572865
。
答案 0 :(得分:8)
python.exe
和pythonw.exe
在运行之前正在优化代码。似乎2**100000000
正在预先计算。这个代码的小编辑:
import time
print("program entered")
def ispow2(n):
return not n & n - 1
start = time.perf_counter()
ispow2(2**100000000)
end = time.perf_counter()
print(end - start)
等待后完全生成以下输出:
program entered
0.01701506924359556
因此,程序在大部分等待之后都不会运行。
表明这是2**...
部分(从命令行运行)的数据:
power of two|approximate wait time|reported time
1000000000 | 6 seconds |0.1637752267742188
10000000000 | 62 seconds |1.6400543291627092
在最后一次运行中,1.5
和program entered
的输出之间有明显的〜1.6400543291627092
秒等待。
答案 1 :(得分:3)
常量是预计算的:
>>> import dis
>>> dis.dis(lambda: 2**100)
1 0 LOAD_CONST 3 (1267650600228229401496703205376)
3 RETURN_VALUE
比较
$ ./python -mtimeit "2**1000"
10000000 loops, best of 3: 0.0601 usec per loop
$ ./python -mtimeit "2**10000"
10000000 loops, best of 3: 0.0584 usec per loop
VS:
$ ./python -mtimeit -s "p=1000" "2**p"
100000 loops, best of 3: 6.89 usec per loop
$ ./python -mtimeit -s "p=10000" "2**p"
10000 loops, best of 3: 94.2 usec per loop
在第一种情况下,在增加功率10次后时间不会改变。它在第二种情况下应该改变,那里的功率是一个变量。
答案 2 :(得分:0)
使用timeit
计算小部分代码的最佳方法如果我在计算机上使用timeit并与你的计算机进行比较,我会使用Python 3.4获得相似的数字:
import time
import timeit
def ispow2(n):
return not n & n - 1
n=10
start = time.time()
for i in range(n):
ispow2(2**100000000)
end = time.time()
print(end - start)
print(timeit.Timer('ispow2(2**100000000)', setup="from __main__ import ispow2").timeit(number=n))
打印:
0.1257798671722412
0.12608672981150448
我使用time.time() vs time.clock(),但两者似乎都有用。