基准测试
我编写了不同的解决方案并进行了比较。我需要将您的值乘以 10 才能获得可衡量的结果。首先没有任何进度测量,看看它在我的机器上运行得有多快。
def process_without_measuring(self):
self._start = time.time()
self._k = 0
while self._k < 100000000:
self._k = self._k+1
print (time.time() - self._start)
我得到 13.8 秒的持续时间。
让我们从你的实现开始:
def process_with_original_measuring(self):
self._start = time.time()
next = self._start
self._k = 0
while self._k < 100000000:
self._k = self._k+1
if time.time() - next > 1:
print (round((self._k / 1000000), 5))
next = time.time()
print("duration:")
print (time.time() - self._start)
如果我运行它,我会得到 30.31 秒 的持续时间,并且每秒增加大约 3%。问题是它必须比较每个循环运行的时间并进行算术运算。您可以通过将循环更改为:
def process_with_manual_measuring(self):
self._start = time.time()
next = self._start + 1
self._k = 0
while self._k < 100000000:
self._k = self._k+1
if time.time() > next:
print (round((self._k / 1000000), 5))
next = time.time() + 1
print("duration:")
print (time.time() - self._start)
我没有在每个循环中减去时间戳,而是只计算下一个时间戳并与之进行比较。这当然不是很快,但比以前更快。它让我达到了 22.0 秒,因此只需删除这一项操作即可节省 8 秒。
使用计时器对象作为线程可以获得更好的结果,这是更可取的方式:
def show_progress(self):
print (round((self._k / 1000000), 5))
self._timer = Timer(1, self.show_progress)
self._timer.start()
def process_with_timer(self):
self._start = time.time()
self._timer = Timer(1, self.show_progress)
self._timer.start()
self._k = 0
while self._k < 100000000:
self._k = self._k+1
self._timer.cancel()
print("duration:")
print (time.time() - self._start)
运行此程序,我每秒获得 7% 的输出,并在 13.8 秒后完成。如您所见,没有区别。只需要再打几个电话,而且这些电话几乎很快就完成了。
如何使用计时器类
Timer 的构造函数需要一个以秒为单位的持续时间以及一个在时间过去后调用的方法。您可以使用类方法、函数或 lambda 表达式。构建完成后,您需要使用start() 启动计时器。
第一个计时器由进程本身启动。在此之后,每次调用计时器都会启动一个新计时器以获取一秒的间隔。当进程完成时,记得在计时器上调用cancel()。否则它将无限运行,因为它会每秒重新启动。
如何运行示例
请注意以上方法是类方法,请注意缩进。
import time
from threading import Timer
class ProgressMeter:
def __init__(self):
self._k = 0
self._timer = 0
# insert above methods with indentation as same level as __init__(self):
要运行它们,您只需要创建一个 ProgressMeter 实例并调用您想要的方法。
meter = ProgressMeter()
meter.process_with_timer()