13.13小节完成
This commit is contained in:
@@ -5,100 +5,102 @@
|
||||
----------
|
||||
问题
|
||||
----------
|
||||
You want to be able to record the time it takes to perform various tasks.
|
||||
你想记录程序执行多个任务所花费的时间
|
||||
|
||||
|
|
||||
|
||||
----------
|
||||
解决方案
|
||||
----------
|
||||
The time module contains various functions for performing timing-related functions.
|
||||
However, it’s often useful to put a higher-level interface on them that mimics a stop
|
||||
watch. For example:
|
||||
``time`` 模块包含很多函数来执行跟时间有关的函数。
|
||||
尽管如此,通常我们会在此基础之上构造一个更高级的接口来模拟一个计时器。例如:
|
||||
|
||||
import time
|
||||
.. code-block:: python
|
||||
|
||||
class Timer:
|
||||
def __init__(self, func=time.perf_counter):
|
||||
self.elapsed = 0.0
|
||||
self._func = func
|
||||
self._start = None
|
||||
import time
|
||||
|
||||
def start(self):
|
||||
if self._start is not None:
|
||||
raise RuntimeError('Already started')
|
||||
self._start = self._func()
|
||||
class Timer:
|
||||
def __init__(self, func=time.perf_counter):
|
||||
self.elapsed = 0.0
|
||||
self._func = func
|
||||
self._start = None
|
||||
|
||||
def stop(self):
|
||||
if self._start is None:
|
||||
raise RuntimeError('Not started')
|
||||
end = self._func()
|
||||
self.elapsed += end - self._start
|
||||
self._start = None
|
||||
def start(self):
|
||||
if self._start is not None:
|
||||
raise RuntimeError('Already started')
|
||||
self._start = self._func()
|
||||
|
||||
def reset(self):
|
||||
self.elapsed = 0.0
|
||||
def stop(self):
|
||||
if self._start is None:
|
||||
raise RuntimeError('Not started')
|
||||
end = self._func()
|
||||
self.elapsed += end - self._start
|
||||
self._start = None
|
||||
|
||||
@property
|
||||
def running(self):
|
||||
return self._start is not None
|
||||
def reset(self):
|
||||
self.elapsed = 0.0
|
||||
|
||||
def __enter__(self):
|
||||
self.start()
|
||||
return self
|
||||
@property
|
||||
def running(self):
|
||||
return self._start is not None
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.stop()
|
||||
def __enter__(self):
|
||||
self.start()
|
||||
return self
|
||||
|
||||
This class defines a timer that can be started, stopped, and reset as needed by the user.
|
||||
It keeps track of the total elapsed time in the elapsed attribute. Here is an example that
|
||||
shows how it can be used:
|
||||
def __exit__(self, *args):
|
||||
self.stop()
|
||||
|
||||
def countdown(n):
|
||||
while n > 0:
|
||||
n -= 1
|
||||
这个类定义了一个可以被用户根据需要启动、停止和重置的计时器。
|
||||
它会在 ``elapsed`` 属性中记录整个消耗时间。
|
||||
下面是一个例子来演示怎样使用它:
|
||||
|
||||
# Use 1: Explicit start/stop
|
||||
t = Timer()
|
||||
t.start()
|
||||
countdown(1000000)
|
||||
t.stop()
|
||||
print(t.elapsed)
|
||||
.. code-block:: python
|
||||
|
||||
# Use 2: As a context manager
|
||||
with t:
|
||||
def countdown(n):
|
||||
while n > 0:
|
||||
n -= 1
|
||||
|
||||
# Use 1: Explicit start/stop
|
||||
t = Timer()
|
||||
t.start()
|
||||
countdown(1000000)
|
||||
t.stop()
|
||||
print(t.elapsed)
|
||||
|
||||
print(t.elapsed)
|
||||
# Use 2: As a context manager
|
||||
with t:
|
||||
countdown(1000000)
|
||||
|
||||
with Timer() as t2:
|
||||
countdown(1000000)
|
||||
print(t2.elapsed)
|
||||
print(t.elapsed)
|
||||
|
||||
with Timer() as t2:
|
||||
countdown(1000000)
|
||||
print(t2.elapsed)
|
||||
|
||||
|
|
||||
|
||||
----------
|
||||
讨论
|
||||
----------
|
||||
This recipe provides a simple yet very useful class for making timing measurements and
|
||||
tracking elapsed time. It’s also a nice illustration of how to support the context-
|
||||
management protocol and the with statement.
|
||||
One issue in making timing measurements concerns the underlying time function used
|
||||
to do it. As a general rule, the accuracy of timing measurements made with functions
|
||||
such as time.time() or time.clock() varies according to the operating system. In
|
||||
contrast, the time.perf_counter() function always uses the highest-resolution timer
|
||||
available on the system.
|
||||
As shown, the time recorded by the Timer class is made according to wall-clock time,
|
||||
and includes all time spent sleeping. If you only want the amount of CPU time used by
|
||||
the process, use time.process_time() instead. For example:
|
||||
本节提供了一个简单而实用的类来实现时间记录以及耗时计算。
|
||||
同时也是对使用with语句以及上下文管理器协议的一个很好的演示。
|
||||
|
||||
t = Timer(time.process_time)
|
||||
with t:
|
||||
countdown(1000000)
|
||||
print(t.elapsed)
|
||||
在计时中要考虑一个底层的时间函数问题。一般来说,
|
||||
使用 ``time.time()`` 或 ``time.clock()`` 计算的时间精度因操作系统的不同会有所不同。
|
||||
而使用 ``time.perf_counter()`` 函数可以确保使用系统上面最精确的计时器。
|
||||
|
||||
Both the time.perf_counter() and time.process_time() return a “time” in fractional
|
||||
seconds. However, the actual value of the time doesn’t have any particular meaning. To
|
||||
make sense of the results, you have to call the functions twice and compute a time
|
||||
difference.
|
||||
More examples of timing and profiling are given in Recipe 14.13.
|
||||
上述代码中由 ``Timer`` 类记录的时间是钟表时间,并包含了所有休眠时间。
|
||||
如果你只想计算该进程所花费的CPU时间,应该使用 ``time.process_time()`` 来代替:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
t = Timer(time.process_time)
|
||||
with t:
|
||||
countdown(1000000)
|
||||
print(t.elapsed)
|
||||
|
||||
``time.perf_counter()`` 和 ``time.process_time()`` 都会返回小数形式的秒数时间。
|
||||
实际的时间值没有任何意义,为了得到有意义的结果,你得执行两次函数然后计算它们的差值。
|
||||
|
||||
更多关于计时和性能分析的例子请参考14.13小节。
|
||||
|
||||
@@ -56,28 +56,28 @@ Roadmap
|
||||
| 13章翻译完成
|
||||
|
||||
|
||||
2015/09/01 - 2015/09/30:
|
||||
2015/09/01 - 2015/11/30:
|
||||
|
||||
::
|
||||
|
||||
| 14章翻译完成
|
||||
|
||||
|
||||
2015/10/01 - 2015/10/31:
|
||||
2015/12/01 - 2015/12/20:
|
||||
|
||||
::
|
||||
|
||||
| 15章翻译完成
|
||||
|
||||
|
||||
2015/11/01 - 2015/11/15:
|
||||
2015/12/21 - 2015/12/31:
|
||||
|
||||
::
|
||||
|
||||
| 对全部翻译进行校对一次
|
||||
|
||||
|
||||
2015/11/16 - 2015/11/20:
|
||||
2016/01/01 - 2016/01/10:
|
||||
|
||||
::
|
||||
|
||||
|
||||
Reference in New Issue
Block a user