#!/usr/bin/env python
'''
Created on May 16, 2011
@author: bungeman
'''
import sys
import getopt
import bench_util
def usage():
"""Prints simple usage information."""
print '-o <file> the old bench output file.'
print '-n <file> the new bench output file.'
print '-h causes headers to be output.'
print '-s <stat> the type of statistical analysis used'
print ' Not specifying is the same as -s "avg".'
print ' avg: average of all data points'
print ' min: minimum of all data points'
print ' med: median of all data points'
print ' 25th: twenty-fifth percentile for all data points'
print '-f <fieldSpec> which fields to output and in what order.'
print ' Not specifying is the same as -f "bctondp".'
print ' b: bench'
print ' c: config'
print ' t: time type'
print ' o: old time'
print ' n: new time'
print ' d: diff'
print ' p: percent diff'
print '-t use tab delimited format for output.'
print '--match <bench> only matches benches which begin with <bench>.'
class BenchDiff:
"""A compare between data points produced by bench.
(BenchDataPoint, BenchDataPoint)"""
def __init__(self, old, new):
self.old = old
self.new = new
self.diff = old.time - new.time
diffp = 0
if old.time != 0:
diffp = self.diff / old.time
self.diffp = diffp
def __repr__(self):
return "BenchDiff(%s, %s)" % (
str(self.new),
str(self.old),
)
def main():
"""Parses command line and writes output."""
try:
opts, _ = getopt.getopt(sys.argv[1:], "f:o:n:s:ht", ['match='])
except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(2)
old = None
new = None
column_format = ""
header_format = ""
columns = 'bctondp'
header = False
stat_type = "avg"
use_tabs = False
match_bench = None;
for option, value in opts:
if option == "-o":
old = value
elif option == "-n":
new = value
elif option == "-h":
header = True
elif option == "-f":
columns = value
elif option == "-s":
stat_type = value
elif option == "-t":
use_tabs = True
elif option == "--match":
match_bench = value
else:
usage()
assert False, "unhandled option"
if old is None or new is None:
usage()
sys.exit(2)
old_benches = bench_util.parse({}, open(old, 'r'), stat_type)
new_benches = bench_util.parse({}, open(new, 'r'), stat_type)
bench_diffs = []
for old_bench in old_benches:
#filter benches by the match criteria
if match_bench and not old_bench.bench.startswith(match_bench):
continue
#filter new_benches for benches that match old_bench
new_bench_match = [bench for bench in new_benches
if old_bench.bench == bench.bench and
old_bench.config == bench.config and
old_bench.time_type == bench.time_type
]
if (len(new_bench_match) < 1):
continue
bench_diffs.append(BenchDiff(old_bench, new_bench_match[0]))
if use_tabs:
column_formats = {
'b' : '{bench}\t',
'c' : '{config}\t',
't' : '{time_type}\t',
'o' : '{old_time: 0.2f}\t',
'n' : '{new_time: 0.2f}\t',
'd' : '{diff: 0.2f}\t',
'p' : '{diffp: 0.1%}\t',
}
header_formats = {
'b' : '{bench}\t',
'c' : '{config}\t',
't' : '{time_type}\t',
'o' : '{old_time}\t',
'n' : '{new_time}\t',
'd' : '{diff}\t',
'p' : '{diffp}\t',
}
else:
bench_max_len = max(map(lambda b: len(b.old.bench), bench_diffs))
config_max_len = max(map(lambda b: len(b.old.config), bench_diffs))
column_formats = {
'b' : '{bench: >%d} ' % (bench_max_len),
'c' : '{config: <%d} ' % (config_max_len),
't' : '{time_type: <4} ',
'o' : '{old_time: >10.2f} ',
'n' : '{new_time: >10.2f} ',
'd' : '{diff: >+10.2f} ',
'p' : '{diffp: >+8.1%} ',
}
header_formats = {
'b' : '{bench: >%d} ' % (bench_max_len),
'c' : '{config: <%d} ' % (config_max_len),
't' : '{time_type: <4} ',
'o' : '{old_time: >10} ',
'n' : '{new_time: >10} ',
'd' : '{diff: >10} ',
'p' : '{diffp: >8} ',
}
for column_char in columns:
if column_formats[column_char]:
column_format += column_formats[column_char]
header_format += header_formats[column_char]
else:
usage()
sys.exit(2)
if header:
print header_format.format(
bench='bench'
, config='conf'
, time_type='time'
, old_time='old'
, new_time='new'
, diff='diff'
, diffp='diffP'
)
bench_diffs.sort(key=lambda d : [d.diffp,
d.old.bench,
d.old.config,
d.old.time_type,
])
for bench_diff in bench_diffs:
print column_format.format(
bench=bench_diff.old.bench.strip()
, config=bench_diff.old.config.strip()
, time_type=bench_diff.old.time_type
, old_time=bench_diff.old.time
, new_time=bench_diff.new.time
, diff=bench_diff.diff
, diffp=bench_diff.diffp
)
if __name__ == "__main__":
main()