|
5 | 5 | ----------
|
6 | 6 | 问题
|
7 | 7 | ----------
|
8 |
| -You want to be able to record the time it takes to perform various tasks. |
| 8 | +你想记录程序执行多个任务所花费的时间 |
9 | 9 |
|
10 | 10 | |
|
11 | 11 |
|
12 | 12 | ----------
|
13 | 13 | 解决方案
|
14 | 14 | ----------
|
15 |
| -The time module contains various functions for performing timing-related functions. |
16 |
| -However, it’s often useful to put a higher-level interface on them that mimics a stop |
17 |
| -watch. For example: |
18 |
| - |
19 |
| -import time |
20 |
| - |
21 |
| -class Timer: |
22 |
| - def __init__(self, func=time.perf_counter): |
23 |
| - self.elapsed = 0.0 |
24 |
| - self._func = func |
25 |
| - self._start = None |
26 |
| - |
27 |
| - def start(self): |
28 |
| - if self._start is not None: |
29 |
| - raise RuntimeError('Already started') |
30 |
| - self._start = self._func() |
31 |
| - |
32 |
| - def stop(self): |
33 |
| - if self._start is None: |
34 |
| - raise RuntimeError('Not started') |
35 |
| - end = self._func() |
36 |
| - self.elapsed += end - self._start |
37 |
| - self._start = None |
38 |
| - |
39 |
| - def reset(self): |
40 |
| - self.elapsed = 0.0 |
41 |
| - |
42 |
| - @property |
43 |
| - def running(self): |
44 |
| - return self._start is not None |
45 |
| - |
46 |
| - def __enter__(self): |
47 |
| - self.start() |
48 |
| - return self |
49 |
| - |
50 |
| - def __exit__(self, *args): |
51 |
| - self.stop() |
52 |
| -
|
53 |
| -This class defines a timer that can be started, stopped, and reset as needed by the user. |
54 |
| -It keeps track of the total elapsed time in the elapsed attribute. Here is an example that |
55 |
| -shows how it can be used: |
56 |
| - |
57 |
| -def countdown(n): |
58 |
| - while n > 0: |
59 |
| - n -= 1 |
60 |
| - |
61 |
| -# Use 1: Explicit start/stop |
62 |
| -t = Timer() |
63 |
| -t.start() |
64 |
| -countdown(1000000) |
65 |
| -t.stop() |
66 |
| -print(t.elapsed) |
67 |
| - |
68 |
| -# Use 2: As a context manager |
69 |
| -with t: |
70 |
| - countdown(1000000) |
| 15 | +``time`` 模块包含很多函数来执行跟时间有关的函数。 |
| 16 | +尽管如此,通常我们会在此基础之上构造一个更高级的接口来模拟一个计时器。例如: |
| 17 | + |
| 18 | +.. code-block:: python |
| 19 | +
|
| 20 | + import time |
| 21 | +
|
| 22 | + class Timer: |
| 23 | + def __init__(self, func=time.perf_counter): |
| 24 | + self.elapsed = 0.0 |
| 25 | + self._func = func |
| 26 | + self._start = None |
| 27 | +
|
| 28 | + def start(self): |
| 29 | + if self._start is not None: |
| 30 | + raise RuntimeError('Already started') |
| 31 | + self._start = self._func() |
| 32 | +
|
| 33 | + def stop(self): |
| 34 | + if self._start is None: |
| 35 | + raise RuntimeError('Not started') |
| 36 | + end = self._func() |
| 37 | + self.elapsed += end - self._start |
| 38 | + self._start = None |
| 39 | +
|
| 40 | + def reset(self): |
| 41 | + self.elapsed = 0.0 |
| 42 | +
|
| 43 | + @property |
| 44 | + def running(self): |
| 45 | + return self._start is not None |
| 46 | +
|
| 47 | + def __enter__(self): |
| 48 | + self.start() |
| 49 | + return self |
| 50 | +
|
| 51 | + def __exit__(self, *args): |
| 52 | + self.stop() |
| 53 | +
|
| 54 | +这个类定义了一个可以被用户根据需要启动、停止和重置的计时器。 |
| 55 | +它会在 ``elapsed`` 属性中记录整个消耗时间。 |
| 56 | +下面是一个例子来演示怎样使用它: |
71 | 57 |
|
72 |
| -print(t.elapsed) |
| 58 | +.. code-block:: python |
73 | 59 |
|
74 |
| -with Timer() as t2: |
| 60 | + def countdown(n): |
| 61 | + while n > 0: |
| 62 | + n -= 1 |
| 63 | +
|
| 64 | + # Use 1: Explicit start/stop |
| 65 | + t = Timer() |
| 66 | + t.start() |
75 | 67 | countdown(1000000)
|
76 |
| -print(t2.elapsed) |
| 68 | + t.stop() |
| 69 | + print(t.elapsed) |
| 70 | +
|
| 71 | + # Use 2: As a context manager |
| 72 | + with t: |
| 73 | + countdown(1000000) |
| 74 | +
|
| 75 | + print(t.elapsed) |
| 76 | +
|
| 77 | + with Timer() as t2: |
| 78 | + countdown(1000000) |
| 79 | + print(t2.elapsed) |
77 | 80 |
|
78 | 81 | |
|
79 | 82 |
|
80 | 83 | ----------
|
81 | 84 | 讨论
|
82 | 85 | ----------
|
83 |
| -This recipe provides a simple yet very useful class for making timing measurements and |
84 |
| -tracking elapsed time. It’s also a nice illustration of how to support the context- |
85 |
| -management protocol and the with statement. |
86 |
| -One issue in making timing measurements concerns the underlying time function used |
87 |
| -to do it. As a general rule, the accuracy of timing measurements made with functions |
88 |
| -such as time.time() or time.clock() varies according to the operating system. In |
89 |
| -contrast, the time.perf_counter() function always uses the highest-resolution timer |
90 |
| -available on the system. |
91 |
| -As shown, the time recorded by the Timer class is made according to wall-clock time, |
92 |
| -and includes all time spent sleeping. If you only want the amount of CPU time used by |
93 |
| -the process, use time.process_time() instead. For example: |
94 |
| - |
95 |
| -t = Timer(time.process_time) |
96 |
| -with t: |
97 |
| - countdown(1000000) |
98 |
| -print(t.elapsed) |
| 86 | +本节提供了一个简单而实用的类来实现时间记录以及耗时计算。 |
| 87 | +同时也是对使用with语句以及上下文管理器协议的一个很好的演示。 |
| 88 | + |
| 89 | +在计时中要考虑一个底层的时间函数问题。一般来说, |
| 90 | +使用 ``time.time()`` 或 ``time.clock()`` 计算的时间精度因操作系统的不同会有所不同。 |
| 91 | +而使用 ``time.perf_counter()`` 函数可以确保使用系统上面最精确的计时器。 |
| 92 | + |
| 93 | +上述代码中由 ``Timer`` 类记录的时间是钟表时间,并包含了所有休眠时间。 |
| 94 | +如果你只想计算该进程所花费的CPU时间,应该使用 ``time.process_time()`` 来代替: |
| 95 | + |
| 96 | +.. code-block:: python |
| 97 | +
|
| 98 | + t = Timer(time.process_time) |
| 99 | + with t: |
| 100 | + countdown(1000000) |
| 101 | + print(t.elapsed) |
| 102 | +
|
| 103 | +``time.perf_counter()`` 和 ``time.process_time()`` 都会返回小数形式的秒数时间。 |
| 104 | +实际的时间值没有任何意义,为了得到有意义的结果,你得执行两次函数然后计算它们的差值。 |
99 | 105 |
|
100 |
| -Both the time.perf_counter() and time.process_time() return a “time” in fractional |
101 |
| -seconds. However, the actual value of the time doesn’t have any particular meaning. To |
102 |
| -make sense of the results, you have to call the functions twice and compute a time |
103 |
| -difference. |
104 |
| -More examples of timing and profiling are given in Recipe 14.13. |
| 106 | +更多关于计时和性能分析的例子请参考14.13小节。 |
0 commit comments