Python 为什么定期按enter键会大大加快我的代码速度?

Python 为什么定期按enter键会大大加快我的代码速度?,python,python-idle,Python,Python Idle,我无意中遇到了一个让我有点困惑的现象。我使用IDLE进行了一些快速测试,我有一些非常简单的代码,如下所示(为了便于说明,我对其进行了简化): 现在我像这样运行了这段代码(多次,基本结果相同): 我的第一个预感是,也许代码运行得更快,因为当我按下enter键时,输出系统可能不必整理那么多的字符串(每次按下enter键时都重新开始)。事实上,在我按下enter键后,输出系统似乎总是立即获得速度提升 我也复习了这本书,但我仍然有点困惑,为什么三个换行符会大大加快速度 不可否认,这个问题有些微不足道,除

我无意中遇到了一个让我有点困惑的现象。我使用IDLE进行了一些快速测试,我有一些非常简单的代码,如下所示(为了便于说明,我对其进行了简化):

现在我像这样运行了这段代码(多次,基本结果相同):

我的第一个预感是,也许代码运行得更快,因为当我按下enter键时,输出系统可能不必整理那么多的字符串(每次按下enter键时都重新开始)。事实上,在我按下enter键后,输出系统似乎总是立即获得速度提升

我也复习了这本书,但我仍然有点困惑,为什么三个换行符会大大加快速度

不可否认,这个问题有些微不足道,除非您想知道如何在空闲状态下加速输出系统而不中止脚本。尽管如此,我还是想了解这里的输出系统发生了什么


(我正在使用Python2.7.x。)

在封面下,IDLE在Tk小部件的顶部模拟终端,我很确定它最终是从Tk小部件派生出来的

长线的存在会稍微减慢小部件的速度。附加到长线比附加到短线需要更长的时间。如果你真的想理解为什么会发生这种情况,你需要看看小部件下面的Tcl代码,它只是一个薄薄的包装

同时,IDLE运行的Tkinter循环做了一些奇怪的事情,允许它在不阻塞循环的情况下接受输入。当它认为没有其他事情发生时,它有时可能会阻塞一小段时间,直到看到输入或Tk事件,所有这些短的阻塞可能会加起来;按Enter键可能只会取消其中的一部分

我不确定这两者中哪一个更相关。你必须用一个只发送长行的程序来测试它,而不是一个每隔(比如)10个数字插入一行新行的程序,然后看看你通过这种方式获得了多少性能改进

通过在我的Mac电脑上的快速测试,原来的程序明显地逐渐变慢,并且在500和920左右有两次量子跳跃。因此,每隔333左右按一次回车键就可以大大加快速度,这是有道理的。你可能会避免这两种量子减速。如果我把它改成只删除逗号,问题就消失了


当然,为每个数字打印换行符可能会导致不同的减速,因为这会使终端足够长,需要滚动,增加滚动缓冲区等。我没有看到空闲时的成本,但在Windows命令行上运行相同的操作,你会发现太多新行的问题和太少空闲行的问题一样糟糕。最好的折衷方法可能是使用“方形”数据,或者不经过检查就尽可能接近80列的数据。

我相信这与您用来执行代码的IDE有关

我已经运行了您的代码(对3.3进行了语法更改),并获得了执行这两次的相同时间:

999 =>8.09542283367021

编辑:这是在使用Python 3.3的空闲库存中执行的。我通过多次实验对enter键进行了垃圾邮件处理,并发现控件v上的字符串输出之间没有时间差。这个实验

凭直觉,我决定删除一个打印函数并将其压缩为一行:

print(i, "=>", clock()-c)
这产生了999=>7.141783124325343

在此基础上,我认为您所看到的时间差异是由于IDE占用了更多线程来处理代码,从而加快了时间。显然,最后的时间是计算和打印for循环的总时间

为了证实我的怀疑,我决定将所有内容都放入一个元组列表中,然后打印该列表

def new_speed_test():
    speed_list = []
    c = clock()
    for i in range(1000):
        speed_list.append((i, clock()-c))
    print(speed_list[-1])
哪个输出:(999,0.0005668934240929957)


总而言之:我的实验证实了IDE是如何处理输出和CPU消耗的。

作为旁注,不要试图用
time.clock()来计时;使用
timeit
。对于像这样的粗粒度测试,存在明显的数量级差异,这不是什么大问题,但值得养成正确操作的习惯。谢谢你的建议。当我在Mac上运行这个程序时,我可以看到它随着线路变长而变慢。它逐渐变慢,还有两个点(大约500点和920点)突然变慢了很多。这意味着这是长线问题,而不是输入阻塞问题……下面的问题是,tcl/tk文本小部件针对屏幕大小的行进行了优化,而对于“长”行则会减慢速度。但它至少能处理500000条短线(这是我测试过的最多的一条)。Windows控制台不会阻塞长线,但只会在环形缓冲区中保留相当少的有限行数。最大值为9999,默认值为300。打印第301行时,删除第1行,依此类推。啊,我明白了。我将查看Tkinter.Text以获得进一步的解释。我会接受这个答案(如果可以的话,我会投票表决,尽管我似乎还没有得到代表)在一点点(只是为了确保没有其他见解出现)。谢谢,我很确定警察已经知道了。这个问题是关于IDLE的输出系统的,甚至承认“这个问题的确有些琐碎,除非你想知道如何在IDLE中加速输出系统而不中断脚本。”我想我在回答之前阅读了这个问题并正确理解了它;然而,在重读之后,我明白了你的意思。可以说,我唯一浪费时间的人是我自己,因此没有造成真正的损害(因为我的答案没有误导性……最坏的情况是,阅读它只是浪费30秒)。是的,它似乎是一个正确的,至少有点有用的评论。毕竟,这次行动只是猜测而已
print(i, "=>", clock()-c)
def new_speed_test():
    speed_list = []
    c = clock()
    for i in range(1000):
        speed_list.append((i, clock()-c))
    print(speed_list[-1])