我有这个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()
我的问题是如何在不减慢实际代码/循环的情况下显示操作的进度。提前致谢; - )
答案 0 :(得分:1)
你的内循环是O(n)时间。如果你经历了大量数据的滞后,那么它很正常。此外,您在执行分割时将x和a转换为浮点数;随着它们变大,它可能会减慢你的过程。
答案 1 :(得分: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的范围迭代到您是素数测试的数字的平方根。
您可以使用此优化来抵消打印进度所造成的任何性能损失。
答案 2 :(得分: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秒,无论哪一个更长的时间。