Python:为什么IDLE运行速度如此缓慢?

24

IDLE 是我最喜欢的 Python 编辑器。它提供了非常好用和直观的 Python shell,对于单元测试和调试非常有用,并且还有一个整洁的调试器。

然而,在 IDLE 下执行的代码非常慢。所谓非常慢,是指比正常速度慢了3个数量级

bash

time echo "for i in range(10000): print 'x'," | python

执行时间为0.052秒,

IDLE

import datetime
start=datetime.datetime.now()
for i in range(10000): print 'x',
end=datetime.datetime.now()
print end-start

接受参数:

>>> 0:01:44.853951

大约慢了2000倍。

有什么想法或者如何改进呢?我猜这可能与后台调试器有关,但我不确定。

Adam


正如答案所示,处理长行的速度缓慢是tcl/tk的面向行的文本小部件的已知问题。在Windows上分发的最新tcl/tk 8.6.4版本与3.5.0版本的结果大致相同。 - Terry Jan Reedy
2个回答

31

问题出在文本输出,而不是调试器。

我刚刚在我的Q6600(3GHz超频)系统上尝试了一下,我的数字甚至更差。但很容易看出,随着添加越来越多的输出文本,性能会下降。

我尝试使用以下方式运行:

1000次迭代 => 7.8秒 2000次迭代 => 28.5秒 3000次迭代 => 70秒

我以前做过一些低级别的TK工作,我知道TkText小部件将文本保存在BTree结构中。逐个字符地附加文本是最糟糕的方法之一,但这似乎是IDLE正在执行的操作。正常的方法是捕获更多数据并附加更大的文本块。

令人惊奇的是,如果您写入print 'x\n',输出速度会更快。3000次迭代只需7秒,而您的10000次迭代只需19秒。

因此,问题绝对与向现有行附加单个字符有关。IDLE程序员不知道TkText的工作原理。

建议是在文本中添加更多换行符或输出更大的文本块,而不仅仅是一个单独的“x”字符。


您是否知道IDLE的开发人员是否将此视为错误?出色而全面的回答给您加1分。 - Adam Matan
这不是IDLE的错误;如果有错误,那么它就在Tkinter的Text小部件中。 - tzot
6
还有IDLE的开发者吗?我以为这个程序已经处于纯维护模式了。我个人认为这是一个bug。 - Lothar
Lothar,我相信之前的IDLE开发人员也很清楚tk Text小部件的工作原理。它肯定是面向行的,但处理长行的能力不佳。这通常不是真正应用程序的特点。虽然任何既生成文本又将文本插入Text小部件的人都可以适当地缓冲和插入大块文本,但IDLE不会生成文本。它只会在程序员指示时插入文本。如果有人说“将1个字符附加到该行”,IDLE就会执行。如果不这样做,那就是一个错误。IDLE无法知道多久之后会再次出现“print”。 - Terry Jan Reedy
很抱歉,Terry,你对线的方向是错误的。我确实读过源代码。而且我非常确定你高估了IDLE开发者在TK方面的技能。 - Lothar
2
tzot:这不是一个错误,而是设计限制 - tk以及许多早期的GUI工具包都会进行即时更新,除非另有规定(批量操作)。新一代工具包,如WPF和JavaFX,已经切换到后台和独立线程进行UI渲染 - 检测小部件树中的更改并根据屏幕刷新率重新绘制 - 这样就消除了上述问题,但也引入了其他类型的开销。在WPF中,他们甚至添加了定时事件回调来解决应用程序层代码中类似的问题。 - jiping-s

11

问题出在Tkinter Text控件上,它对于非常长的行的管理效率较低,而您刚刚创建了这样一行。 您会注意到,即使很长的行的任何部分可见,所有滚动都非常缓慢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接