''' Created on May 16, 2011 @author: bungeman ''' import sys import getopt import re def parse(lines): """Takes iterable lines of bench output, returns {bench:{config:time}}.""" benches = {} current_bench = None for line in lines: #see if this line starts a new bench new_bench = re.search('running bench \[\d+ \d+\] (.{28})', line) if new_bench: current_bench = new_bench.group(1) #add configs on this line to the current bench if current_bench: for new_config in re.finditer(' (.{4}): msecs = (\d+\.\d+)', line): current_config = new_config.group(1) current_time = float(new_config.group(2)) if current_bench in benches: benches[current_bench][current_config] = current_time else: benches[current_bench] = {current_config : current_time} return benches def usage(): """Prints simple usage information.""" print '-o the old bench output file.' print '-n the new bench output file.' print '-h causes headers to be output.' print '-f which fields to output and in what order.' print ' Not specifying is the same as -f "bcondp".' print ' b: bench' print ' c: config' print ' o: old time' print ' n: new time' print ' d: diff' print ' p: percent diff' def main(): """Parses command line and writes output.""" try: opts, args = getopt.getopt(sys.argv[1:], "f:o:n:h") except getopt.GetoptError, err: print str(err) usage() sys.exit(2) column_formats = { 'b' : '{bench: >28} ', 'c' : '{config: <4} ', 'o' : '{old_time: >10.2f} ', 'n' : '{new_time: >10.2f} ', 'd' : '{diff: >+10.2f} ', 'p' : '{diffp: >+7.1%} ', } header_formats = { 'b' : '{bench: >28} ', 'c' : '{config: <4} ', 'o' : '{old_time: >10} ', 'n' : '{new_time: >10} ', 'd' : '{diff: >10} ', 'p' : '{diffp: >7} ', } old = None new = None column_format = "" header_format = "" columns = 'bcondp' header = False 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 else: usage() assert False, "unhandled option" if old is None or new is None: usage() sys.exit(2) 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' , old_time='old' , new_time='new' , diff='diff' , diffp='diffP' ) old_benches = parse(open(old, 'r')) new_benches = parse(open(new, 'r')) for old_bench, old_configs in old_benches.items(): if old_bench in new_benches: new_configs = new_benches[old_bench] for old_config, old_time in old_configs.items(): if old_config in new_configs: new_time = new_configs[old_config] old_time = old_configs[old_config] print column_format.format( bench=old_bench.strip() , config=old_config.strip() , old_time=old_time , new_time=new_time , diff=(old_time - new_time) , diffp=((old_time-new_time)/old_time) ) if __name__ == "__main__": main()