Python显示进度

时间:2014-06-13 15:53:20

标签: python python-2.7 progress-bar primes progress

我有这个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 :(得分: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秒,无论哪一个更长的时间。