isa*_*acg 9 python python-idle python-3.4
编辑:我完全重做了这个问题.这个问题与time.time()无关
这是一个程序:
import time
start=time.time()
a=9<<(1<<26) # The line that makes it take a while
print(time.time()-start)
Run Code Online (Sandbox Code Playgroud)
当程序保存为文件并在Python 3.4中使用IDLE运行时,大约需要10秒,即使打印出0.0 time.time().IDLE非常清楚这个问题,因为从命令行运行时,这个程序几乎没有时间.
另一个具有相同效果的程序,如senshin所发现的,是:
def f():
a = 9<<(1<<26)
Run Code Online (Sandbox Code Playgroud)
我已经确认,当在Python 2.7 IDLE或python 2.7或3.4上的命令行中运行时,这个程序几乎是即时的.
那么什么是Python 3.4 IDLE这样做需要这么长时间?我知道计算这个数字并将其保存到内存是磁盘密集型的,但我想知道的是为什么Python 3.4 IDLE执行此计算并在Python 2.7 IDLE和命令行Python可能不会执行时编写.
我会看着那条线并将其拆开。你有:
9 << (1 << 26)
(1 << 26)是第一个计算的表达式,它产生一个非常大的数字。这行代码的意思是,您要将数字 1 乘以 2 的 26 次方,从而有效地2 ** 26在内存中生成数字。但这不是问题。然后将 9 左移 2 ** 26。这会产生一个在内存中长度约为 5000 万位的数字(我什至无法精确计算!),因为左移太大了。未来要小心,因为看似很小的变化实际上会增长得非常快。如果它更大,您的程序可能根本无法运行。9 * 2 ** (2 ** 26)如果您好奇的话,您的表达式在数学上的计算结果为。
注释部分中的歧义实际上可能是在处理 python 在幕后如何处理这巨大的内存部分,而不是 IDLE。
编辑1:
我认为正在发生的事情是,即使将数学表达式放置在尚未调用的函数内部,只要该表达式是自足的,数学表达式也会计算出其答案。这意味着,如果在方程中使用变量,则该方程在字节代码中将保持不变,并且直到硬执行才进行计算。该函数必须被解释,在这个过程中,我认为你的值实际上是被计算出来的,导致时间变慢。我对此不确定,但我强烈怀疑这种行为是根本原因。即使事实并非如此,你也必须承认这9<<(1<<26)会让计算机落后,那里没有太多可以做的优化。
In[73]: def create_number():
return 9<<(1<<26)
In[74]: #Note that this seems instantaneous, but try calling the function!
In[75]: %timeit create_number()
#Python environment crashes because task is too hard
Run Code Online (Sandbox Code Playgroud)
然而,这种测试存在轻微的欺骗。当用常规时间尝试这个时,我得到:
In[3]: from timeit import timeit
In[4]: timeit(setup = 'from __main__ import create_number', stmt = 'create_number()', number = 1)
Out[4]: .004942887388800443
Run Code Online (Sandbox Code Playgroud)
另请记住,打印该值是不可能的,因此:
In[102]: 9<<(1<<26)
甚至不应该尝试。
如需更多额外支持:
我感觉自己像个叛逆者,所以我决定看看如果我对方程的原始执行进行计时会发生什么:
In[107]: %timeit 9<<(1<<26)
10000000 loops, best of 3: 22.8 ns per loop
In[108]: def empty(): pass
In[109]: %timeit empty()
10000000 loops, best of 3: 96.3 ns per loop
Run Code Online (Sandbox Code Playgroud)
这确实很可疑,因为显然这个计算发生的速度比 Python 调用空函数的时间要快,但事实显然并非如此。我再说一遍,这不是瞬时的,但可能与检索内存中某处已计算的对象并重用该值来计算表达式有关。无论如何,好问题。