bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 1 | ''' |
| 2 | Created on May 16, 2011 |
| 3 | |
| 4 | @author: bungeman |
| 5 | ''' |
| 6 | import sys |
| 7 | import getopt |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 8 | import bench_util |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 9 | |
| 10 | def usage(): |
| 11 | """Prints simple usage information.""" |
| 12 | |
| 13 | print '-o <file> the old bench output file.' |
| 14 | print '-n <file> the new bench output file.' |
| 15 | print '-h causes headers to be output.' |
djsollen@google.com | f3d3d96 | 2012-08-21 19:10:05 +0000 | [diff] [blame] | 16 | print '-s <stat> the type of statistical analysis used' |
| 17 | print ' Not specifying is the same as -s "avg".' |
| 18 | print ' avg: average of all data points' |
| 19 | print ' min: minimum of all data points' |
| 20 | print ' med: median of all data points' |
| 21 | print ' 25th: twenty-fifth percentile for all data points' |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 22 | print '-f <fieldSpec> which fields to output and in what order.' |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 23 | print ' Not specifying is the same as -f "bctondp".' |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 24 | print ' b: bench' |
| 25 | print ' c: config' |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 26 | print ' t: time type' |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 27 | print ' o: old time' |
| 28 | print ' n: new time' |
| 29 | print ' d: diff' |
| 30 | print ' p: percent diff' |
| 31 | |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 32 | class BenchDiff: |
| 33 | """A compare between data points produced by bench. |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 34 | |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 35 | (BenchDataPoint, BenchDataPoint)""" |
| 36 | def __init__(self, old, new): |
| 37 | self.old = old |
| 38 | self.new = new |
| 39 | self.diff = old.time - new.time |
| 40 | diffp = 0 |
| 41 | if old.time != 0: |
| 42 | diffp = self.diff / old.time |
| 43 | self.diffp = diffp |
| 44 | |
| 45 | def __repr__(self): |
| 46 | return "BenchDiff(%s, %s)" % ( |
| 47 | str(self.new), |
| 48 | str(self.old), |
| 49 | ) |
| 50 | |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 51 | def main(): |
| 52 | """Parses command line and writes output.""" |
| 53 | |
| 54 | try: |
djsollen@google.com | f3d3d96 | 2012-08-21 19:10:05 +0000 | [diff] [blame] | 55 | opts, _ = getopt.getopt(sys.argv[1:], "f:o:n:s:h") |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 56 | except getopt.GetoptError, err: |
| 57 | print str(err) |
| 58 | usage() |
| 59 | sys.exit(2) |
| 60 | |
| 61 | column_formats = { |
| 62 | 'b' : '{bench: >28} ', |
| 63 | 'c' : '{config: <4} ', |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 64 | 't' : '{time_type: <4} ', |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 65 | 'o' : '{old_time: >10.2f} ', |
| 66 | 'n' : '{new_time: >10.2f} ', |
| 67 | 'd' : '{diff: >+10.2f} ', |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 68 | 'p' : '{diffp: >+8.1%} ', |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 69 | } |
| 70 | header_formats = { |
| 71 | 'b' : '{bench: >28} ', |
| 72 | 'c' : '{config: <4} ', |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 73 | 't' : '{time_type: <4} ', |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 74 | 'o' : '{old_time: >10} ', |
| 75 | 'n' : '{new_time: >10} ', |
| 76 | 'd' : '{diff: >10} ', |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 77 | 'p' : '{diffp: >8} ', |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 78 | } |
| 79 | |
| 80 | old = None |
| 81 | new = None |
| 82 | column_format = "" |
| 83 | header_format = "" |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 84 | columns = 'bctondp' |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 85 | header = False |
djsollen@google.com | f3d3d96 | 2012-08-21 19:10:05 +0000 | [diff] [blame] | 86 | stat_type = "avg" |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 87 | |
| 88 | for option, value in opts: |
| 89 | if option == "-o": |
| 90 | old = value |
| 91 | elif option == "-n": |
| 92 | new = value |
| 93 | elif option == "-h": |
| 94 | header = True |
| 95 | elif option == "-f": |
| 96 | columns = value |
djsollen@google.com | f3d3d96 | 2012-08-21 19:10:05 +0000 | [diff] [blame] | 97 | elif option == "-s": |
| 98 | stat_type = value |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 99 | else: |
| 100 | usage() |
| 101 | assert False, "unhandled option" |
| 102 | |
| 103 | if old is None or new is None: |
| 104 | usage() |
| 105 | sys.exit(2) |
| 106 | |
| 107 | for column_char in columns: |
| 108 | if column_formats[column_char]: |
| 109 | column_format += column_formats[column_char] |
| 110 | header_format += header_formats[column_char] |
| 111 | else: |
| 112 | usage() |
| 113 | sys.exit(2) |
| 114 | |
| 115 | if header: |
| 116 | print header_format.format( |
| 117 | bench='bench' |
| 118 | , config='conf' |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 119 | , time_type='time' |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 120 | , old_time='old' |
| 121 | , new_time='new' |
| 122 | , diff='diff' |
| 123 | , diffp='diffP' |
| 124 | ) |
| 125 | |
djsollen@google.com | f3d3d96 | 2012-08-21 19:10:05 +0000 | [diff] [blame] | 126 | old_benches = bench_util.parse({}, open(old, 'r'), stat_type) |
| 127 | new_benches = bench_util.parse({}, open(new, 'r'), stat_type) |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 128 | |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 129 | bench_diffs = [] |
| 130 | for old_bench in old_benches: |
| 131 | #filter new_benches for benches that match old_bench |
| 132 | new_bench_match = [bench for bench in new_benches |
| 133 | if old_bench.bench == bench.bench and |
| 134 | old_bench.config == bench.config and |
| 135 | old_bench.time_type == bench.time_type |
| 136 | ] |
| 137 | if (len(new_bench_match) < 1): |
| 138 | continue |
| 139 | bench_diffs.append(BenchDiff(old_bench, new_bench_match[0])) |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 140 | |
bungeman@google.com | 85669f9 | 2011-06-17 13:58:14 +0000 | [diff] [blame] | 141 | bench_diffs.sort(key=lambda d : [d.diffp, |
| 142 | d.old.bench, |
| 143 | d.old.config, |
| 144 | d.old.time_type, |
| 145 | ]) |
| 146 | for bench_diff in bench_diffs: |
| 147 | print column_format.format( |
| 148 | bench=bench_diff.old.bench.strip() |
| 149 | , config=bench_diff.old.config.strip() |
| 150 | , time_type=bench_diff.old.time_type |
| 151 | , old_time=bench_diff.old.time |
| 152 | , new_time=bench_diff.new.time |
| 153 | , diff=bench_diff.diff |
| 154 | , diffp=bench_diff.diffp |
| 155 | ) |
bungeman@google.com | d1a416a | 2011-05-18 18:37:07 +0000 | [diff] [blame] | 156 | |
| 157 | if __name__ == "__main__": |
| 158 | main() |