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