blob: f6909b10b062cff341184984d592b37f6de6323c [file] [log] [blame]
bungeman@google.comd1a416a2011-05-18 18:37:07 +00001'''
2Created on May 16, 2011
3
4@author: bungeman
5'''
6import sys
7import getopt
8import re
9
10def parse(lines):
11 """Takes iterable lines of bench output, returns {bench:{config:time}}."""
12
13 benches = {}
14 current_bench = None
15
16 for line in lines:
17 #see if this line starts a new bench
18 new_bench = re.search('running bench \[\d+ \d+\] (.{28})', line)
19 if new_bench:
20 current_bench = new_bench.group(1)
21
22 #add configs on this line to the current bench
23 if current_bench:
24 for new_config in re.finditer(' (.{4}): msecs = (\d+\.\d+)', line):
25 current_config = new_config.group(1)
26 current_time = float(new_config.group(2))
27 if current_bench in benches:
28 benches[current_bench][current_config] = current_time
29 else:
30 benches[current_bench] = {current_config : current_time}
31
32 return benches
33
34def usage():
35 """Prints simple usage information."""
36
37 print '-o <file> the old bench output file.'
38 print '-n <file> the new bench output file.'
39 print '-h causes headers to be output.'
40 print '-f <fieldSpec> which fields to output and in what order.'
41 print ' Not specifying is the same as -f "bcondp".'
42 print ' b: bench'
43 print ' c: config'
44 print ' o: old time'
45 print ' n: new time'
46 print ' d: diff'
47 print ' p: percent diff'
48
49
50def main():
51 """Parses command line and writes output."""
52
53 try:
54 opts, args = getopt.getopt(sys.argv[1:], "f:o:n:h")
55 except getopt.GetoptError, err:
56 print str(err)
57 usage()
58 sys.exit(2)
59
60 column_formats = {
61 'b' : '{bench: >28} ',
62 'c' : '{config: <4} ',
63 'o' : '{old_time: >10.2f} ',
64 'n' : '{new_time: >10.2f} ',
65 'd' : '{diff: >+10.2f} ',
66 'p' : '{diffp: >+7.1%} ',
67 }
68 header_formats = {
69 'b' : '{bench: >28} ',
70 'c' : '{config: <4} ',
71 'o' : '{old_time: >10} ',
72 'n' : '{new_time: >10} ',
73 'd' : '{diff: >10} ',
74 'p' : '{diffp: >7} ',
75 }
76
77 old = None
78 new = None
79 column_format = ""
80 header_format = ""
81 columns = 'bcondp'
82 header = False
83
84 for option, value in opts:
85 if option == "-o":
86 old = value
87 elif option == "-n":
88 new = value
89 elif option == "-h":
90 header = True
91 elif option == "-f":
92 columns = value
93 else:
94 usage()
95 assert False, "unhandled option"
96
97 if old is None or new is None:
98 usage()
99 sys.exit(2)
100
101 for column_char in columns:
102 if column_formats[column_char]:
103 column_format += column_formats[column_char]
104 header_format += header_formats[column_char]
105 else:
106 usage()
107 sys.exit(2)
108
109 if header:
110 print header_format.format(
111 bench='bench'
112 , config='conf'
113 , old_time='old'
114 , new_time='new'
115 , diff='diff'
116 , diffp='diffP'
117 )
118
119 old_benches = parse(open(old, 'r'))
120 new_benches = parse(open(new, 'r'))
121
122 for old_bench, old_configs in old_benches.items():
123 if old_bench in new_benches:
124 new_configs = new_benches[old_bench]
125 for old_config, old_time in old_configs.items():
126 if old_config in new_configs:
127 new_time = new_configs[old_config]
128 old_time = old_configs[old_config]
129 print column_format.format(
130 bench=old_bench.strip()
131 , config=old_config.strip()
132 , old_time=old_time
133 , new_time=new_time
134 , diff=(old_time - new_time)
135 , diffp=((old_time-new_time)/old_time)
136 )
137
138
139if __name__ == "__main__":
140 main()