为什么 IDLE 3.4 在这个程序上花费这么长时间?

2024-01-10

编辑:我正在完全重做这个问题。该问题与 time.time() 无关

这是一个程序:

import time
start=time.time()
a=9<<(1<<26)             # The line that makes it take a while
print(time.time()-start)

这个程序,当保存为文件并在 Python 3.4 中使用 IDLE 运行时,需要大约 10 秒,即使从 0.0 打印出来time.time()。 IDLE 的问题非常明显,因为当从命令行运行时,该程序几乎不需要任何时间。

senshin 发现的另一个具有相同效果的程序是:

def f(): 
    a = 9<<(1<<26)

我已经确认,当在 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。

EDIT 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

然而,这种测试存在轻微的欺骗。当用常规时间尝试这个时,我得到:

In[3]: from timeit import timeit
In[4]: timeit(setup = 'from __main__ import create_number', stmt = 'create_number()', number = 1)
Out[4]: .004942887388800443

另请记住,打印该值是不可能的,因此:

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

这确实很可疑,因为显然这个计算发生的速度比 Python 调用空函数的时间要快,但事实显然并非如此。我再说一遍,这不是瞬时的,但可能与检索内存中某处已计算的对象有关,并重用该值计算表达方式。无论如何,好问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 IDLE 3.4 在这个程序上花费这么长时间? 的相关文章

随机推荐