Selaa lähdekoodia

Convert performance measurements to LaTeX charts

jonathanvdc 8 vuotta sitten
vanhempi
commit
1dacbb9635
2 muutettua tiedostoa jossa 114 lisäystä ja 1 poistoa
  1. 101 0
      performance/perf2tex.py
  2. 13 1
      performance/utils.py

+ 101 - 0
performance/perf2tex.py

@@ -0,0 +1,101 @@
+"""Converts performance data files (as produced by utils.py) to LaTeX charts."""
+
+import utils
+
+# Generated LaTeX is based on the accepted answer to
+# http://tex.stackexchange.com/questions/101320/grouped-bar-chart
+
+# pylint: disable=I0011,W0141
+
+LATEX_COLORS = [
+    ('chartBlue', 0x4F81BD),
+    ('chartRed', 0xC0504D),
+    ('chartGreen', 0x9BBB59),
+    ('chartPurple', 0x9F4C7C)
+]
+
+LATEX_HEADER = r"""\documentclass[12pt,a4paper,onecolumn,openright]{report}
+\usepackage{xcolor}
+\usepackage{pgfplots}
+\usepackage{tikz}
+\usepgfplotslibrary{units}
+
+% Define bar chart colors
+%"""
+
+LATEX_DOCUMENT_HEADER = r"""\begin{document}
+\begin{tikzpicture}"""
+
+LATEX_DOCUMENT_FOOTER = r"""\end{tikzpicture}
+\end{document}"""
+
+def encode_latex_string(value):
+    """Encodes the given string as a LaTeX string."""
+    # I guess this is good enough for now. This may need to be
+    # revisited if we encounter more complicated names.
+    return value.replace('_', '\\_')
+
+def assemble_latex_chart(optimization_levels, color_defs, test_names, data):
+    """Assembles a LaTeX chart from the given components."""
+    lines = []
+    lines.append(LATEX_HEADER)
+    for color in color_defs:
+        lines.append(r'\definecolor{%s}{HTML}{%X}' % color)
+    lines.append(LATEX_DOCUMENT_HEADER)
+    lines.append(r"""
+    \begin{axis}[
+        width = 0.85*\textwidth,
+        height = 8cm,
+        major x tick style = transparent,
+        ybar=2*\pgflinewidth,
+        bar width=14pt,
+        ymajorgrids = true,
+        ylabel = {Run time},
+        symbolic x coords={%s},
+        xtick = data,
+        scaled y ticks = false,
+        enlarge x limits=0.25,
+        ymin=0,
+        y unit=s,
+        legend cell align=left,
+        legend style={
+                at={(1,1.05)},
+                anchor=south east,
+                column sep=1ex
+        }
+    ]""" % ','.join(map(encode_latex_string, test_names)))
+    for color_name, points in data:
+        lines.append(r"""
+        \addplot[style={%s,fill=%s,mark=none}]
+            coordinates {%s};""" % (
+                color_name, color_name,
+                ' '.join([('(%s,%s)' % (encode_latex_string(name), measurement))
+                          for name, measurement in points])))
+    lines.append(r"""
+        \legend{%s}""" % ','.join(map(encode_latex_string, optimization_levels)))
+    lines.append(r"""
+    \end{axis}""")
+    lines.append(LATEX_DOCUMENT_FOOTER)
+    return '\n'.join(lines)
+
+def create_latex_chart(perf_data):
+    """Creates a LaTeX chart for the given performance data."""
+    unused_colors = LATEX_COLORS[:]
+    opt_levels = []
+    color_defs = []
+    test_names = []
+    data = []
+    for optimization_level, measurements in perf_data:
+        color = unused_colors.pop(0)
+        color_name, _ = color
+        opt_levels.append(optimization_level)
+        color_defs.append(color)
+        data.append((color_name, measurements))
+        for name, _ in measurements:
+            if name not in test_names:
+                test_names.append(name)
+
+    return assemble_latex_chart(opt_levels, color_defs, test_names, data)
+
+if __name__ == '__main__':
+    print(create_latex_chart(utils.parse_perf_data(utils.DEFAULT_PERF_FILE_NAME)))

+ 13 - 1
performance/utils.py

@@ -10,6 +10,7 @@ import urllib2
 import subprocess
 import signal
 import random
+import operator
 
 sys.path.append("interface/HUTN")
 sys.path.append("scripts")
@@ -246,4 +247,15 @@ DEFAULT_PERF_FILE_NAME = 'perf_data.txt'
 def write_perf_to_file(test_name, optimization_level, result, file_name=DEFAULT_PERF_FILE_NAME):
     """Writes performance data to a file."""
     with open(file_name, "a") as perf_file:
-        perf_file.write('%s:%s %f\n' % (test_name, optimization_level, result))
+        perf_file.write('%s:%s:%f\n' % (test_name, optimization_level, result))
+
+def parse_perf_data(file_name):
+    """Parses the performance data in the given file."""
+    results = {}
+    with open(file_name, 'r') as perf_file:
+        for line in perf_file.readlines():
+            test_name, optimization_level, result = line.strip().split(':')
+            if optimization_level not in results:
+                results[optimization_level] = []
+            results[optimization_level].append((test_name, result))
+    return sorted(results.items(), key=operator.itemgetter(1))