• 13.13 实现一个计时器
    • 问题
    • 解决方案
    • 讨论

    13.13 实现一个计时器

    问题

    你想记录程序执行多个任务所花费的时间

    解决方案

    time 模块包含很多函数来执行跟时间有关的函数。尽管如此,通常我们会在此基础之上构造一个更高级的接口来模拟一个计时器。例如:

    1. import time
    2.  
    3. class Timer:
    4. def __init__(self, func=time.perf_counter):
    5. self.elapsed = 0.0
    6. self._func = func
    7. self._start = None
    8.  
    9. def start(self):
    10. if self._start is not None:
    11. raise RuntimeError('Already started')
    12. self._start = self._func()
    13.  
    14. def stop(self):
    15. if self._start is None:
    16. raise RuntimeError('Not started')
    17. end = self._func()
    18. self.elapsed += end - self._start
    19. self._start = None
    20.  
    21. def reset(self):
    22. self.elapsed = 0.0
    23.  
    24. @property
    25. def running(self):
    26. return self._start is not None
    27.  
    28. def __enter__(self):
    29. self.start()
    30. return self
    31.  
    32. def __exit__(self, *args):
    33. self.stop()

    这个类定义了一个可以被用户根据需要启动、停止和重置的计时器。它会在 elapsed 属性中记录整个消耗时间。下面是一个例子来演示怎样使用它:

    1. def countdown(n):
    2. while n > 0:
    3. n -= 1
    4.  
    5. # Use 1: Explicit start/stop
    6. t = Timer()
    7. t.start()
    8. countdown(1000000)
    9. t.stop()
    10. print(t.elapsed)
    11.  
    12. # Use 2: As a context manager
    13. with t:
    14. countdown(1000000)
    15.  
    16. print(t.elapsed)
    17.  
    18. with Timer() as t2:
    19. countdown(1000000)
    20. print(t2.elapsed)

    讨论

    本节提供了一个简单而实用的类来实现时间记录以及耗时计算。同时也是对使用with语句以及上下文管理器协议的一个很好的演示。

    在计时中要考虑一个底层的时间函数问题。一般来说,使用 time.time()time.clock() 计算的时间精度因操作系统的不同会有所不同。而使用 time.perf_counter() 函数可以确保使用系统上面最精确的计时器。

    上述代码中由 Timer 类记录的时间是钟表时间,并包含了所有休眠时间。如果你只想计算该进程所花费的CPU时间,应该使用 time.process_time() 来代替:

    1. t = Timer(time.process_time)
    2. with t:
    3. countdown(1000000)
    4. print(t.elapsed)

    time.perf_counter()time.process_time() 都会返回小数形式的秒数时间。实际的时间值没有任何意义,为了得到有意义的结果,你得执行两次函数然后计算它们的差值。

    更多关于计时和性能分析的例子请参考14.13小节。

    原文:

    http://python3-cookbook.readthedocs.io/zh_CN/latest/c13/p13_making_stopwatch_timer.html