Browse Source

benchlog: Add gnuplot support

generate plot image of benchlog by gnuplot (if system has gnuplot)

Change-Id: Ib7d94313bf061c008267f30b339f92f4ea336b3a
Reviewed-on: https://code-review.googlesource.com/3150
Reviewed-by: Paul Wankadia <junyer@google.com>
Chiu-Hsiang Hsu 3 years ago
parent
commit
65bdcdf40a
1 changed files with 98 additions and 0 deletions
  1. 98 0
      benchlog/benchplot.py

+ 98 - 0
benchlog/benchplot.py

@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+import argparse     # for ArgumentParser
+import subprocess   # for Popen
+import tempfile     # for NamedTemporaryFile
+import os           # for remove
+
+class gnuplot(object):
+
+    output = "result.png"
+
+    script = """
+             set terminal png size 1024, 768
+             set output "{}.png"
+             set title "re2 benchlog"
+             set datafile separator ";"
+             set grid x y
+             set ylabel "MB/s"
+             set autoscale
+             plot """
+
+    template = """'{}' using 1:5:xticlabels(2) with linespoints linewidth 3 title "{}",\\\n"""
+
+    benchdata = dict()
+    tempfiles = []
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        """
+        remove all temporary files
+        """
+
+        for filename in self.tempfiles:
+            os.remove(filename)
+
+    def parse_re2_benchlog(self, filename):
+        """
+        parse the input benchlog and return a dictionary contain bench data
+        """
+
+        benchdata = self.benchdata
+
+        with open(filename) as f:
+
+            for raw in f.readlines():
+
+                data = raw.split('\t')
+
+                if len(data) == 4:
+
+                    data = data[0].split('/') + data[1:]
+                    data = list(map(str.strip, data))
+
+                    if not benchdata.get(data[0]):
+                        benchdata[data[0]] = [ data[1:] ]
+                    else:
+                        benchdata[data[0]].append(data[1:])
+
+    def gen_csv(self):
+        """
+        generate temporary csv files
+        """
+
+        for name, data in self.benchdata.items():
+
+            with tempfile.NamedTemporaryFile(delete=False) as f:
+
+                for index, line in enumerate(data):
+                    f.write('{};{}\n'.format(index, ';'.join(line)).encode())
+
+                self.tempfiles.append(f.name)
+                self.script = self.script + self.template.format(f.name, name)
+
+    def run(self):
+        self.gen_csv()
+        script = self.script[:-3].format(self.output)
+        command = subprocess.Popen(['gnuplot'], stdin=subprocess.PIPE)
+        command.communicate(script.encode())
+
+
+if __name__ == '__main__':
+
+    parser = argparse.ArgumentParser(description='generate plots for benchlog')
+    parser.add_argument('benchlog', type=str, help='benchlog generated by re2')
+    args = parser.parse_args()
+
+    try:
+        subprocess.Popen(['gnuplot'], stdin=subprocess.PIPE)
+    except FileNotFoundError:
+        print('you can install "gnuplot" to generate plots automatically')
+        exit(1)
+
+    with gnuplot() as plot:
+        plot.output = args.benchlog
+        plot.parse_re2_benchlog(args.benchlog)
+        plot.run()