为什么时间错误报告这么快的时间?

时间:2014-05-09 05:32:31

标签: python python-3.x time

我正在玩大数字,并写下以下代码:

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

为什么时间模块报告这么快的时间显然需要比运行代码更长的时间?


根据timeclock()已被弃用,因此我将其切换为process_time()。我得到了几乎相同的结果。与perf_counter()相同。


注意:这是从IDLE运行的。当我从命令行运行时,时间似乎准确报告。也许pythonw.exe与此有关,但是什么?

但是,当我在0的末尾添加另一个2**10...时,命令行需要约7秒,但报告0.1781140373572865

3 个答案:

答案 0 :(得分:8)

python.exepythonw.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.5program 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(),但两者似乎都有用。