#!/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()