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