Python 显示进度
我有一段用Python写的代码,用来生成质数。我在代码中加了一小段代码(在# Start progress code
和# End progress code
之间),用来显示操作的进度,但这样反而让操作变慢了。
#!/usr/bin/python
a = input("Enter a number: ")
f = open('data.log', 'w')
for x in range (2, a):
p = 1
# Start progress code
s = (float(x)/float(a))*100
print '\rProcessing ' + str(s) + '%',
# End progress code
for i in range(2, x-1):
c = x % i
if c == 0:
p = 0
break
if p != 0:
f.write(str(x) + ", ")
print '\rData written to \'data.log\'. Press Enter to exit...'
raw_input()
我的问题是,怎样才能在不影响实际代码或循环速度的情况下显示操作进度呢?谢谢大家提前的帮助;-)
3 个回答
0
首先,我希望这只是个简单的问题,因为(看起来)整个操作的复杂度是O(n^2),也就是说它会随着数据量的增加变得越来越慢。
你可能想把这个放在最前面:
from __future__ import division # Make floating point division the default and enable the "//" integer division operator.
通常在处理很大的循环时,如果每次循环的开销不大,就不会在每次循环中输出进度,因为这样会花费太多时间(正如你所说的那样)。可以尝试每隔固定的次数或者固定的时间输出一次进度:
N_OUTPUTS = 100
OUTPUT_EVERY = (a-2) // 5
...
# Start progress code
if a % OUTPUT_EVERY == 0:
print '\rProcessing {}%'.format(x/a),
# End progress code
或者如果你想按时间来控制的话:
UPDATE_DT = 0.5
import time
t = time.time()
...
# Start progress code
if time.time() - t > UPDATE_DT:
print '\rProcessing {}%'.format(x/a),
t = time.time()
# End progress code
这样做会稍微增加一些开销,但可以确保即使内部循环变慢,你也不会在每次循环中等待超过一次或者0.5秒,取哪个更长就用哪个。
1
你的内层循环的时间复杂度是O(n)。如果你在处理很大的数字时感觉到卡顿,那是很正常的。另外,在进行除法运算时,你把x和a转换成了浮点数;当这些数字变得更大时,这可能会让你的程序变慢。
1
为了回答你的问题,输入输出(I/O)是非常耗费资源的,所以打印你的进度会对性能产生很大的影响。如果可以的话,尽量避免打印。
如果你担心速度,有一个很好的优化方法可以大大加快你的代码运行速度。
在你的内层循环中,不要这样写:
for i in range(2, x-1):
c = x % i
if c == 0:
p = 0
break
而是使用:
for i in range(2, x-1**(1.0/2)):
c = x % i
if c == 0:
p = 0
break
你只需要从2开始,循环到你要测试的数字的平方根。
你可以利用这个优化来弥补因为打印进度而造成的性能损失。