10b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger'''
20b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerCreated on May 16, 2011
30b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
40b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger@author: bungeman
50b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger'''
60b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerimport sys
70b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerimport getopt
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerimport bench_util
90b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerdef usage():
110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    """Prints simple usage information."""
120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    print '-o <file> the old bench output file.'
140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    print '-n <file> the new bench output file.'
150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    print '-h causes headers to be output.'
160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    print '-f <fieldSpec> which fields to output and in what order.'
171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    print '   Not specifying is the same as -f "bctondp".'
180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    print '  b: bench'
190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    print '  c: config'
201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    print '  t: time type'
210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    print '  o: old time'
220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    print '  n: new time'
230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    print '  d: diff'
240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    print '  p: percent diff'
250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass BenchDiff:
271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    """A compare between data points produced by bench.
281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    (BenchDataPoint, BenchDataPoint)"""
301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    def __init__(self, old, new):
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        self.old = old
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        self.new = new
331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        self.diff = old.time - new.time
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        diffp = 0
351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if old.time != 0:
361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            diffp = self.diff / old.time
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        self.diffp = diffp
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    def __repr__(self):
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return "BenchDiff(%s, %s)" % (
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                   str(self.new),
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                   str(self.old),
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger               )
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerdef main():
460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    """Parses command line and writes output."""
470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    try:
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        opts, _ = getopt.getopt(sys.argv[1:], "f:o:n:h")
500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    except getopt.GetoptError, err:
510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        print str(err)
520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        usage()
530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        sys.exit(2)
540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    column_formats = {
560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        'b' : '{bench: >28} ',
570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        'c' : '{config: <4} ',
581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        't' : '{time_type: <4} ',
590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        'o' : '{old_time: >10.2f} ',
600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        'n' : '{new_time: >10.2f} ',
610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        'd' : '{diff: >+10.2f} ',
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        'p' : '{diffp: >+8.1%} ',
630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    header_formats = {
650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        'b' : '{bench: >28} ',
660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        'c' : '{config: <4} ',
671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        't' : '{time_type: <4} ',
680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        'o' : '{old_time: >10} ',
690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        'n' : '{new_time: >10} ',
700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        'd' : '{diff: >10} ',
711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        'p' : '{diffp: >8} ',
720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    old = None
750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    new = None
760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    column_format = ""
770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    header_format = ""
781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    columns = 'bctondp'
790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    header = False
800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    for option, value in opts:
820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if option == "-o":
830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            old = value
840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        elif option == "-n":
850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            new = value
860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        elif option == "-h":
870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            header = True
880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        elif option == "-f":
890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            columns = value
900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        else:
910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            usage()
920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            assert False, "unhandled option"
930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if old is None or new is None:
950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        usage()
960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        sys.exit(2)
970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    for column_char in columns:
990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if column_formats[column_char]:
1000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            column_format += column_formats[column_char]
1010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            header_format += header_formats[column_char]
1020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        else:
1030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            usage()
1040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            sys.exit(2)
1050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if header:
1070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        print header_format.format(
1080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            bench='bench'
1090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            , config='conf'
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            , time_type='time'
1110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            , old_time='old'
1120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            , new_time='new'
1130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            , diff='diff'
1140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            , diffp='diffP'
1150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        )
1160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    old_benches = bench_util.parse({}, open(old, 'r'))
1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    new_benches = bench_util.parse({}, open(new, 'r'))
1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bench_diffs = []
1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for old_bench in old_benches:
1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        #filter new_benches for benches that match old_bench
1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        new_bench_match = [bench for bench in new_benches
1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if old_bench.bench == bench.bench and
1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger               old_bench.config == bench.config and
1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger               old_bench.time_type == bench.time_type
1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        ]
1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (len(new_bench_match) < 1):
1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            continue
1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bench_diffs.append(BenchDiff(old_bench, new_bench_match[0]))
1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bench_diffs.sort(key=lambda d : [d.diffp,
1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     d.old.bench,
1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     d.old.config,
1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     d.old.time_type,
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    ])
1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for bench_diff in bench_diffs:
1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        print column_format.format(
1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            bench=bench_diff.old.bench.strip()
1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            , config=bench_diff.old.config.strip()
1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            , time_type=bench_diff.old.time_type
1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            , old_time=bench_diff.old.time
1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            , new_time=bench_diff.new.time
1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            , diff=bench_diff.diff
1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            , diffp=bench_diff.diffp
1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        )
1470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerif __name__ == "__main__":
1490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    main()
150