1# Copyright 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import time
6
7
8class Timer(object):
9  '''A simple timer which starts when constructed and stops when Stop is called.
10  '''
11
12  def __init__(self):
13    self._start = time.time()
14    self._elapsed = None
15
16  def Stop(self):
17    '''Stops the timer. Must only be called once. Returns |self|.
18    '''
19    assert self._elapsed is None
20    self._elapsed = time.time() - self._start
21    return self
22
23  def With(self, other):
24    '''Returns a new stopped Timer with this Timer's elapsed time + |other|'s.
25    Both Timers must already be stopped.
26    '''
27    assert self._elapsed is not None
28    assert other._elapsed is not None
29    self_and_other = Timer()
30    self_and_other._start = min(self._start, other._start)
31    self_and_other._elapsed = self._elapsed + other._elapsed
32    return self_and_other
33
34  def FormatElapsed(self):
35    '''Returns the elapsed time as a string in a pretty format; as a whole
36    number in either seconds or milliseconds depending on which is more
37    appropriate. Must already be Stopped.
38    '''
39    assert self._elapsed is not None
40    elapsed = self._elapsed
41    if elapsed < 1:
42      elapsed = int(elapsed * 1000)
43      unit = 'ms'
44    else:
45      elapsed = int(elapsed)
46      unit = 'second' if elapsed == 1 else 'seconds'
47    return '%s %s' % (elapsed, unit)
48
49
50def TimerClosure(closure, *args, **optargs):
51  '''A shorthand for timing a single function call. Returns a tuple of
52  (closure return value, timer).
53  '''
54  timer = Timer()
55  try:
56    return closure(*args, **optargs), timer
57  finally:
58    timer.Stop()
59