소스 검색

Give perf2tex a command-line interface

jonathanvdc 8 년 전
부모
커밋
3a7c31f907
1개의 변경된 파일65개의 추가작업 그리고 8개의 파일을 삭제
  1. 65 8
      performance/perf2tex.py

+ 65 - 8
performance/perf2tex.py

@@ -1,7 +1,7 @@
 """Converts performance data files (as produced by utils.py) to LaTeX charts."""
 
+import argparse
 import colorsys
-import operator
 import utils
 
 # Generated LaTeX is based on the accepted answer to
@@ -79,15 +79,14 @@ def assemble_latex_chart(optimization_levels, color_defs, test_names, data):
 
 def create_latex_chart(perf_data):
     """Creates a LaTeX chart for the given performance data."""
-    perf_data_dict = {opt_level: dict(tests) for opt_level, tests in perf_data}
-    sorted_opt_levels = sort_by_runtime(perf_data_dict)
+    sorted_opt_levels = sort_by_runtime(perf_data)
     color_scheme = generate_color_scheme(sorted_opt_levels)
     opt_levels = []
     color_defs = []
     test_names = []
     data = []
     for i, optimization_level in enumerate(sorted_opt_levels):
-        measurements = perf_data_dict[optimization_level]
+        measurements = perf_data[optimization_level]
         color = color_scheme[optimization_level]
         color_name = 'chartColor%d' % i
         opt_levels.append(optimization_level)
@@ -140,10 +139,21 @@ def get_relative_measurements(perf_data, baseline_optimization_level):
 
     return results
 
+def perf_list_to_dict(perf_list):
+    """Converts performance data from a list representation to a dictionary representation."""
+    return {opt_level: dict(tests) for opt_level, tests in perf_list}
+
+def perf_dict_to_list(perf_dict):
+    """Converts performance data from a dictionary representation to a list representation."""
+    return [(opt_level, tests.items()) for opt_level, tests in perf_dict.items()]
+
 def interpolate(value_range, index, length):
     """Uses an index and a length to interpolate in the given range."""
     min_val, max_val = value_range
-    return min_val + float(index) * (max_val - min_val) / float(length - 1)
+    if length == 1:
+        return max_val
+    else:
+        return min_val + float(index) * (max_val - min_val) / float(length - 1)
 
 def sort_by_runtime(perf_data):
     """Sorts the optimization levels by mean relative runtimes."""
@@ -170,7 +180,54 @@ def generate_color_scheme(sorted_opt_levels):
 
     return color_scheme
 
+def main():
+    arg_parser = argparse.ArgumentParser()
+    arg_parser.add_argument('input', help='The performance data file.')
+    arg_parser.add_argument(
+        '-q', '--quantity', type=str,
+        help="The quantity to build a bar chart for. Defaults to '%s'" % utils.TOTAL_TIME_QUANTITY,
+        default=utils.TOTAL_TIME_QUANTITY)
+    arg_parser.add_argument(
+        '-O', '--opt', type=str, nargs='*',
+        help="Filters on optimization levels.")
+    arg_parser.add_argument(
+        '-t', '--test', type=str, nargs='*',
+        help="Filters on tests.")
+    arg_parser.add_argument(
+        '-r', '--relative', action='store_const', const=True,
+        help="Produce bars that are relative to some baseline.", default=False)
+
+    args = arg_parser.parse_args()
+
+    perf_data = utils.parse_perf_data(args.input)[args.quantity]
+
+    if args.opt:
+        optimization_set = set(args.opt)
+        perf_data = [
+            (optimization_level, measurements)
+            for optimization_level, measurements in perf_data
+            if optimization_level in optimization_set]
+
+    if args.test:
+        test_set = set(args.test)
+        new_perf_data = []
+        for optimization_level, measurements in perf_data:
+            new_measurements = []
+            for test_name, data_point in measurements:
+                if test_name in test_set:
+                    new_measurements.append((test_name, data_point))
+
+            if len(new_measurements) > 0:
+                new_perf_data.append((optimization_level, new_measurements))
+        perf_data = new_perf_data
+
+    perf_data_dict = perf_list_to_dict(perf_data)
+
+    if args.relative:
+        baseline_opt_level = get_baseline_optimization_level(perf_data_dict)
+        perf_data_dict = get_relative_measurements(perf_data_dict, baseline_opt_level)
+
+    print(create_latex_chart(perf_data_dict))
+
 if __name__ == '__main__':
-    print(
-        create_latex_chart(
-            utils.parse_perf_data(utils.DEFAULT_PERF_FILE_NAME)[utils.TOTAL_TIME_QUANTITY]))
+    main()