Zachary Turner | c1b7cd7 | 2015-11-05 19:22:28 +0000 | [diff] [blame] | 1 | from __future__ import absolute_import |
| 2 | |
| 3 | # System modules |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 +0000 | [diff] [blame] | 4 | import time |
Zachary Turner | c1b7cd7 | 2015-11-05 19:22:28 +0000 | [diff] [blame] | 5 | |
| 6 | # Third-party modules |
| 7 | |
| 8 | # LLDB modules |
| 9 | from .lldbtest import * |
Johnny Chen | 985e740 | 2011-08-01 21:13:26 +0000 | [diff] [blame] | 10 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 11 | |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 +0000 | [diff] [blame] | 12 | class Stopwatch(object): |
| 13 | """Stopwatch provides a simple utility to start/stop your stopwatch multiple |
| 14 | times. Each start/stop is equal to a lap, with its elapsed time accumulated |
| 15 | while measurment is in progress. |
| 16 | |
| 17 | When you're ready to start from scratch for another round of measurements, |
| 18 | be sure to call the reset() method. |
| 19 | |
| 20 | For example, |
| 21 | |
| 22 | sw = Stopwatch() |
| 23 | for i in range(1000): |
| 24 | with sw: |
| 25 | # Do some length operations... |
| 26 | ... |
| 27 | # Get the average time. |
| 28 | avg_time = sw.avg() |
| 29 | |
| 30 | # Reset the stopwatch as we are about to perform other kind of operations. |
| 31 | sw.reset() |
| 32 | ... |
| 33 | """ |
| 34 | |
| 35 | ############################################################# |
| 36 | # |
| 37 | # Context manager interfaces to support the 'with' statement. |
| 38 | # |
| 39 | ############################################################# |
| 40 | |
| 41 | def __enter__(self): |
| 42 | """ |
| 43 | Context management protocol on entry to the body of the with statement. |
| 44 | """ |
| 45 | return self.start() |
| 46 | |
| 47 | def __exit__(self, type, value, tb): |
| 48 | """ |
| 49 | Context management protocol on exit from the body of the with statement. |
| 50 | """ |
| 51 | self.stop() |
| 52 | |
| 53 | def reset(self): |
| 54 | self.__laps__ = 0 |
| 55 | self.__total_elapsed__ = 0.0 |
| 56 | self.__start__ = None |
| 57 | self.__stop__ = None |
| 58 | self.__elapsed__ = 0.0 |
Johnny Chen | 09e87a6 | 2011-10-27 00:32:03 +0000 | [diff] [blame] | 59 | self.__nums__ = [] |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 +0000 | [diff] [blame] | 60 | |
| 61 | def __init__(self): |
| 62 | self.reset() |
| 63 | |
| 64 | def start(self): |
| 65 | if self.__start__ is None: |
| 66 | self.__start__ = time.time() |
| 67 | else: |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 68 | raise Exception( |
| 69 | "start() already called, did you forget to stop() first?") |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 +0000 | [diff] [blame] | 70 | # Return self to facilitate the context manager __enter__ protocol. |
| 71 | return self |
| 72 | |
| 73 | def stop(self): |
| 74 | if self.__start__ is not None: |
| 75 | self.__stop__ = time.time() |
| 76 | elapsed = self.__stop__ - self.__start__ |
| 77 | self.__total_elapsed__ += elapsed |
| 78 | self.__laps__ += 1 |
Johnny Chen | 09e87a6 | 2011-10-27 00:32:03 +0000 | [diff] [blame] | 79 | self.__nums__.append(elapsed) |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 80 | self.__start__ = None # Reset __start__ to be None again. |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 +0000 | [diff] [blame] | 81 | else: |
| 82 | raise Exception("stop() called without first start()?") |
| 83 | |
| 84 | def laps(self): |
| 85 | """Gets the number of laps. One lap is equal to a start/stop action.""" |
| 86 | return self.__laps__ |
| 87 | |
| 88 | def avg(self): |
| 89 | """Equal to total elapsed time divided by the number of laps.""" |
| 90 | return self.__total_elapsed__ / self.__laps__ |
| 91 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 92 | # def sigma(self): |
Johnny Chen | 09e87a6 | 2011-10-27 00:32:03 +0000 | [diff] [blame] | 93 | # """Return the standard deviation of the available samples.""" |
| 94 | # if self.__laps__ <= 0: |
| 95 | # return None |
| 96 | # return numpy.std(self.__nums__) |
| 97 | |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 +0000 | [diff] [blame] | 98 | def __str__(self): |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 99 | return "Avg: %f (Laps: %d, Total Elapsed Time: %f, min=%f, max=%f)" % (self.avg( |
| 100 | ), self.__laps__, self.__total_elapsed__, min(self.__nums__), max(self.__nums__)) |
| 101 | |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 +0000 | [diff] [blame] | 102 | |
Johnny Chen | 2a6eab0 | 2011-10-20 01:35:57 +0000 | [diff] [blame] | 103 | class BenchBase(TestBase): |
Johnny Chen | 985e740 | 2011-08-01 21:13:26 +0000 | [diff] [blame] | 104 | """ |
| 105 | Abstract base class for benchmark tests. |
| 106 | """ |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 107 | |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 +0000 | [diff] [blame] | 108 | def setUp(self): |
| 109 | """Fixture for unittest test case setup.""" |
Johnny Chen | 2a6eab0 | 2011-10-20 01:35:57 +0000 | [diff] [blame] | 110 | super(BenchBase, self).setUp() |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 111 | # TestBase.setUp(self) |
Johnny Chen | da0384c | 2011-08-02 00:50:55 +0000 | [diff] [blame] | 112 | self.stopwatch = Stopwatch() |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 +0000 | [diff] [blame] | 113 | |
| 114 | def tearDown(self): |
| 115 | """Fixture for unittest test case teardown.""" |
Johnny Chen | 6acfb69 | 2012-04-19 23:50:00 +0000 | [diff] [blame] | 116 | super(BenchBase, self).tearDown() |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 117 | # TestBase.tearDown(self) |
Johnny Chen | da0384c | 2011-08-02 00:50:55 +0000 | [diff] [blame] | 118 | del self.stopwatch |