[9b26b7]: / deepvariant / vendor / timer.py

Download this file

260 lines (201 with data), 7.3 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# Copyright 2017 Google LLC.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""This module implements classes useful for timing how long an action took."""
import time
class TimerError(Exception):
"""Timer Error Exception."""
class Timer(object):
"""Measure time elapsed since some event.
Example usage:
from deepvariant.vendor import timer
a_timer = timer.Timer()
a_timer.Start()
# Do stuff here ...
a_timer.Stop()
if a_timer.GetDuration() > 100:
print 'This took too long'
Another way to use this class is the with statement:
with timer.Timer() as t:
# Do time consuming stuff ...
print 'Time consuming stuff took %f seconds.' % t.GetDuration()
"""
def __init__(self):
"""Initializes a timer."""
self.duration = 0
self.running = False
self.start = None
def Start(self):
"""Resets and starts a timer."""
self._StartInternal()
def Stop(self):
"""Stops a timer, and records the duration.
Stop is idempotent.
Returns:
The duration, i.e., the time (in seconds) for which the timer ran.
"""
self._StopInternal()
return self.duration
def __enter__(self):
"""Resets and starts a timer.
This allows Timer to be used as a ContextManager type.
Returns:
The object itself so that it can be bound to a variable in a with
statement.
"""
self._StartInternal()
return self
def __exit__(self, unused_ex_type, unused_ex, unused_ex_trace):
"""Stops a timer and records the duration.
This allows Timer to be used as a ContextManager type.
Returns:
False. This means that any exceptions raised within the body of the
caller's with statement will propagate up the stack without interference.
"""
self._StopInternal()
return False
def _StartInternal(self):
"""Resets and starts a timer.
Common implementation for Start and __enter__.
"""
self.start = time.time()
self.running = 1
def _StopInternal(self):
"""Stops a timer and records the duration.
Common implementation for Stop and __exit__.
"""
if self.running:
self.duration = time.time() - self.start
self.running = 0
def IsRunning(self):
return self.running
def __str__(self):
return str(self.GetDuration())
def GetDuration(self):
"""Returns the elapsed time, in seconds.
Returns:
If timer is still running: the time (in seconds) elapsed since the start
Otherwise: the time (in seconds) for which the timer ran.
"""
if self.running:
return time.time() - self.start
else:
return self.duration
def GetStartTime(self):
"""Returns start time of the timer.
Returns:
The start time of the timer, floating-point seconds since the epoch.
Raises:
TimerError: if the timer was not started
"""
if self.start:
return self.start
else:
raise TimerError('TimerNotStarted')
def GetStopTime(self):
"""Returns stop time of the timer.
Returns:
The stop time of the timer, floating-point seconds since the epoch.
Raises:
TimerError: if the timer was never started or is still running
"""
if not self.start:
raise TimerError('TimerNotStarted')
elif self.running:
raise TimerError('TimerStillRunning')
else:
return self.start + self.duration
class TimerStart(Timer):
"""A timer that automatically starts when you construct it.
This is otherwise identical in interface to the Timer class in this module.
"""
def __init__(self):
Timer.__init__(self)
self.Start()
class MultiIntervalTimer(Timer):
"""A timer that records cumulative time intervals.
Example usage:
from deepvariant.vendor import timer
a_timer = timer.MultiIntervalTimer()
# Do stuff the first time
a_timer.Start()
# ... stuff ...
a_timer.Stop()
# Do stuff the second time (repeat as many times as you like)
a_timer.Start()
# ... stuff ...
a_timer.Stop()
if a_timer.GetDuration() > 1000:
print 'Total time spent doing stuff is too much!'
Another way to use this class is the with statement:
t = timer.MultiIntervalTimer()
with t:
# Do stuff the first time
with t:
# Do stuff the second time (repeat as many times as you like)
print 'Total time spent doing stuff was %f seconds.' % t.GetDuration()
"""
def __init__(self):
super(MultiIntervalTimer, self).__init__()
self.stop = None
def Reset(self):
"""Resets the measured cumulative time to zero."""
self.duration = 0
def _StopInternal(self):
"""Stops a timer and adds the current duration to the total.
Common implementation for Stop and __exit__.
"""
if self.running:
self.stop = time.time()
self.duration += self.stop - self.start
self.running = 0
def GetDuration(self):
"""Returns the total elapsed time, in seconds.
Returns:
The total time (in seconds) accumulated so far, regardless of counter
state (i.e. if stopped, total time spent in all running windows; if
running, total time spent in all previous running windows plus time
elapsed from the last call to Start() until GetDuration() was called).
"""
if self.running:
return self.duration + (time.time() - self.start)
else:
return self.duration
def GetStopTime(self):
"""Returns the last stop time of the timer.
Returns:
The last stop time of the timer, same format as time.time()
Raises:
TimerError: if the timer was never started or is still running
"""
if not self.start:
return super(MultiIntervalTimer, self).GetStopTime()
elif self.running:
return super(MultiIntervalTimer, self).GetStopTime()
else:
return self.stop