blob: f4f773442e7fa149173ed6016a42be021f7f9aaf [file] [log] [blame]
bungeman@google.com70476652013-01-30 19:22:51 +00001#!/usr/bin/env python
bungeman@google.comd1a416a2011-05-18 18:37:07 +00002'''
3Created on May 16, 2011
4
5@author: bungeman
6'''
7import sys
8import getopt
bungeman@google.com85669f92011-06-17 13:58:14 +00009import bench_util
bungeman@google.comd1a416a2011-05-18 18:37:07 +000010
11def usage():
12 """Prints simple usage information."""
bungeman@google.com70476652013-01-30 19:22:51 +000013
bungeman@google.comd1a416a2011-05-18 18:37:07 +000014 print '-o <file> the old bench output file.'
15 print '-n <file> the new bench output file.'
16 print '-h causes headers to be output.'
djsollen@google.comf3d3d962012-08-21 19:10:05 +000017 print '-s <stat> the type of statistical analysis used'
18 print ' Not specifying is the same as -s "avg".'
19 print ' avg: average of all data points'
20 print ' min: minimum of all data points'
21 print ' med: median of all data points'
22 print ' 25th: twenty-fifth percentile for all data points'
bungeman@google.comd1a416a2011-05-18 18:37:07 +000023 print '-f <fieldSpec> which fields to output and in what order.'
bungeman@google.com85669f92011-06-17 13:58:14 +000024 print ' Not specifying is the same as -f "bctondp".'
bungeman@google.comd1a416a2011-05-18 18:37:07 +000025 print ' b: bench'
26 print ' c: config'
bungeman@google.com85669f92011-06-17 13:58:14 +000027 print ' t: time type'
bungeman@google.comd1a416a2011-05-18 18:37:07 +000028 print ' o: old time'
29 print ' n: new time'
30 print ' d: diff'
31 print ' p: percent diff'
bungeman@google.com70476652013-01-30 19:22:51 +000032 print '-t use tab delimited format for output.'
33 print '--match <bench> only matches benches which begin with <bench>.'
34
bungeman@google.com85669f92011-06-17 13:58:14 +000035class BenchDiff:
36 """A compare between data points produced by bench.
bungeman@google.com70476652013-01-30 19:22:51 +000037
bungeman@google.com85669f92011-06-17 13:58:14 +000038 (BenchDataPoint, BenchDataPoint)"""
39 def __init__(self, old, new):
40 self.old = old
41 self.new = new
42 self.diff = old.time - new.time
43 diffp = 0
44 if old.time != 0:
45 diffp = self.diff / old.time
46 self.diffp = diffp
bungeman@google.com70476652013-01-30 19:22:51 +000047
bungeman@google.com85669f92011-06-17 13:58:14 +000048 def __repr__(self):
49 return "BenchDiff(%s, %s)" % (
50 str(self.new),
51 str(self.old),
52 )
bungeman@google.com70476652013-01-30 19:22:51 +000053
bungeman@google.comd1a416a2011-05-18 18:37:07 +000054def main():
55 """Parses command line and writes output."""
bungeman@google.com70476652013-01-30 19:22:51 +000056
bungeman@google.comd1a416a2011-05-18 18:37:07 +000057 try:
bungeman@google.com70476652013-01-30 19:22:51 +000058 opts, _ = getopt.getopt(sys.argv[1:], "f:o:n:s:ht", ['match='])
bungeman@google.comd1a416a2011-05-18 18:37:07 +000059 except getopt.GetoptError, err:
60 print str(err)
61 usage()
62 sys.exit(2)
bungeman@google.com70476652013-01-30 19:22:51 +000063
bungeman@google.comd1a416a2011-05-18 18:37:07 +000064 old = None
65 new = None
66 column_format = ""
67 header_format = ""
bungeman@google.com85669f92011-06-17 13:58:14 +000068 columns = 'bctondp'
bungeman@google.comd1a416a2011-05-18 18:37:07 +000069 header = False
djsollen@google.comf3d3d962012-08-21 19:10:05 +000070 stat_type = "avg"
bungeman@google.com70476652013-01-30 19:22:51 +000071 use_tabs = False
72 match_bench = None;
73
bungeman@google.comd1a416a2011-05-18 18:37:07 +000074 for option, value in opts:
75 if option == "-o":
76 old = value
77 elif option == "-n":
78 new = value
79 elif option == "-h":
80 header = True
81 elif option == "-f":
82 columns = value
djsollen@google.comf3d3d962012-08-21 19:10:05 +000083 elif option == "-s":
84 stat_type = value
bungeman@google.com70476652013-01-30 19:22:51 +000085 elif option == "-t":
86 use_tabs = True
87 elif option == "--match":
88 match_bench = value
bungeman@google.comd1a416a2011-05-18 18:37:07 +000089 else:
90 usage()
91 assert False, "unhandled option"
bungeman@google.com70476652013-01-30 19:22:51 +000092
bungeman@google.comd1a416a2011-05-18 18:37:07 +000093 if old is None or new is None:
94 usage()
95 sys.exit(2)
bungeman@google.com70476652013-01-30 19:22:51 +000096
97 old_benches = bench_util.parse({}, open(old, 'r'), stat_type)
98 new_benches = bench_util.parse({}, open(new, 'r'), stat_type)
99
100 bench_diffs = []
101 for old_bench in old_benches:
102 #filter benches by the match criteria
103 if match_bench and not old_bench.bench.startswith(match_bench):
104 continue
105
106 #filter new_benches for benches that match old_bench
107 new_bench_match = [bench for bench in new_benches
108 if old_bench.bench == bench.bench and
109 old_bench.config == bench.config and
110 old_bench.time_type == bench.time_type
111 ]
112 if (len(new_bench_match) < 1):
113 continue
114 bench_diffs.append(BenchDiff(old_bench, new_bench_match[0]))
115
116 if use_tabs:
117 column_formats = {
118 'b' : '{bench}\t',
119 'c' : '{config}\t',
120 't' : '{time_type}\t',
121 'o' : '{old_time: 0.2f}\t',
122 'n' : '{new_time: 0.2f}\t',
123 'd' : '{diff: 0.2f}\t',
124 'p' : '{diffp: 0.1%}\t',
125 }
126 header_formats = {
127 'b' : '{bench}\t',
128 'c' : '{config}\t',
129 't' : '{time_type}\t',
130 'o' : '{old_time}\t',
131 'n' : '{new_time}\t',
132 'd' : '{diff}\t',
133 'p' : '{diffp}\t',
134 }
135 else:
136 bench_max_len = max(map(lambda b: len(b.old.bench), bench_diffs))
137 config_max_len = max(map(lambda b: len(b.old.config), bench_diffs))
138 column_formats = {
139 'b' : '{bench: >%d} ' % (bench_max_len),
140 'c' : '{config: <%d} ' % (config_max_len),
141 't' : '{time_type: <4} ',
142 'o' : '{old_time: >10.2f} ',
143 'n' : '{new_time: >10.2f} ',
144 'd' : '{diff: >+10.2f} ',
145 'p' : '{diffp: >+8.1%} ',
146 }
147 header_formats = {
148 'b' : '{bench: >%d} ' % (bench_max_len),
149 'c' : '{config: <%d} ' % (config_max_len),
150 't' : '{time_type: <4} ',
151 'o' : '{old_time: >10} ',
152 'n' : '{new_time: >10} ',
153 'd' : '{diff: >10} ',
154 'p' : '{diffp: >8} ',
155 }
156
bungeman@google.comd1a416a2011-05-18 18:37:07 +0000157 for column_char in columns:
158 if column_formats[column_char]:
159 column_format += column_formats[column_char]
160 header_format += header_formats[column_char]
161 else:
162 usage()
163 sys.exit(2)
bungeman@google.com70476652013-01-30 19:22:51 +0000164
bungeman@google.comd1a416a2011-05-18 18:37:07 +0000165 if header:
166 print header_format.format(
167 bench='bench'
168 , config='conf'
bungeman@google.com85669f92011-06-17 13:58:14 +0000169 , time_type='time'
bungeman@google.comd1a416a2011-05-18 18:37:07 +0000170 , old_time='old'
171 , new_time='new'
172 , diff='diff'
173 , diffp='diffP'
174 )
bungeman@google.com70476652013-01-30 19:22:51 +0000175
bungeman@google.com85669f92011-06-17 13:58:14 +0000176 bench_diffs.sort(key=lambda d : [d.diffp,
177 d.old.bench,
178 d.old.config,
179 d.old.time_type,
180 ])
181 for bench_diff in bench_diffs:
182 print column_format.format(
183 bench=bench_diff.old.bench.strip()
184 , config=bench_diff.old.config.strip()
185 , time_type=bench_diff.old.time_type
186 , old_time=bench_diff.old.time
187 , new_time=bench_diff.new.time
188 , diff=bench_diff.diff
189 , diffp=bench_diff.diffp
190 )
bungeman@google.com70476652013-01-30 19:22:51 +0000191
bungeman@google.comd1a416a2011-05-18 18:37:07 +0000192if __name__ == "__main__":
193 main()