Johnny Chen | 2352af8 | 2011-08-02 00:43:09 | [diff] [blame] | 1 | import time |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 | [diff] [blame] | 2 | from lldbtest import Base |
Johnny Chen | aaa82ff | 2011-08-02 22:54:37 | [diff] [blame] | 3 | from lldbtest import benchmarks_test |
| 4 | from lldbtest import line_number |
Johnny Chen | 985e740 | 2011-08-01 21:13:26 | [diff] [blame] | 5 | |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 | [diff] [blame] | 6 | class Stopwatch(object): |
| 7 | """Stopwatch provides a simple utility to start/stop your stopwatch multiple |
| 8 | times. Each start/stop is equal to a lap, with its elapsed time accumulated |
| 9 | while measurment is in progress. |
| 10 | |
| 11 | When you're ready to start from scratch for another round of measurements, |
| 12 | be sure to call the reset() method. |
| 13 | |
| 14 | For example, |
| 15 | |
| 16 | sw = Stopwatch() |
| 17 | for i in range(1000): |
| 18 | with sw: |
| 19 | # Do some length operations... |
| 20 | ... |
| 21 | # Get the average time. |
| 22 | avg_time = sw.avg() |
| 23 | |
| 24 | # Reset the stopwatch as we are about to perform other kind of operations. |
| 25 | sw.reset() |
| 26 | ... |
| 27 | """ |
| 28 | |
| 29 | ############################################################# |
| 30 | # |
| 31 | # Context manager interfaces to support the 'with' statement. |
| 32 | # |
| 33 | ############################################################# |
| 34 | |
| 35 | def __enter__(self): |
| 36 | """ |
| 37 | Context management protocol on entry to the body of the with statement. |
| 38 | """ |
| 39 | return self.start() |
| 40 | |
| 41 | def __exit__(self, type, value, tb): |
| 42 | """ |
| 43 | Context management protocol on exit from the body of the with statement. |
| 44 | """ |
| 45 | self.stop() |
| 46 | |
| 47 | def reset(self): |
| 48 | self.__laps__ = 0 |
| 49 | self.__total_elapsed__ = 0.0 |
| 50 | self.__start__ = None |
| 51 | self.__stop__ = None |
| 52 | self.__elapsed__ = 0.0 |
| 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 |
| 71 | self.__start__ = None # Reset __start__ to be None again. |
| 72 | else: |
| 73 | raise Exception("stop() called without first start()?") |
| 74 | |
| 75 | def laps(self): |
| 76 | """Gets the number of laps. One lap is equal to a start/stop action.""" |
| 77 | return self.__laps__ |
| 78 | |
| 79 | def avg(self): |
| 80 | """Equal to total elapsed time divided by the number of laps.""" |
| 81 | return self.__total_elapsed__ / self.__laps__ |
| 82 | |
| 83 | def __str__(self): |
Johnny Chen | aaa82ff | 2011-08-02 22:54:37 | [diff] [blame] | 84 | return "Avg: %f (Laps: %d, Total Elapsed Time: %f)" % (self.avg(), |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 | [diff] [blame] | 85 | self.__laps__, |
| 86 | self.__total_elapsed__) |
| 87 | |
| 88 | class BenchBase(Base): |
Johnny Chen | 985e740 | 2011-08-01 21:13:26 | [diff] [blame] | 89 | """ |
| 90 | Abstract base class for benchmark tests. |
| 91 | """ |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 | [diff] [blame] | 92 | def setUp(self): |
| 93 | """Fixture for unittest test case setup.""" |
| 94 | Base.setUp(self) |
Johnny Chen | da0384c | 2011-08-02 00:50:55 | [diff] [blame] | 95 | self.stopwatch = Stopwatch() |
Johnny Chen | 2352af8 | 2011-08-02 00:43:09 | [diff] [blame] | 96 | |
| 97 | def tearDown(self): |
| 98 | """Fixture for unittest test case teardown.""" |
| 99 | Base.tearDown(self) |
Johnny Chen | da0384c | 2011-08-02 00:50:55 | [diff] [blame] | 100 | del self.stopwatch |
Johnny Chen | 985e740 | 2011-08-01 21:13:26 | [diff] [blame] | 101 | |