1*ccdc9c3eSSadaf Ebrahimi#!/usr/bin/env python 2*ccdc9c3eSSadaf Ebrahimi 3*ccdc9c3eSSadaf Ebrahimiimport argparse # for ArgumentParser 4*ccdc9c3eSSadaf Ebrahimiimport subprocess # for Popen 5*ccdc9c3eSSadaf Ebrahimiimport tempfile # for NamedTemporaryFile 6*ccdc9c3eSSadaf Ebrahimiimport os # for remove 7*ccdc9c3eSSadaf Ebrahimi 8*ccdc9c3eSSadaf Ebrahimiclass gnuplot(object): 9*ccdc9c3eSSadaf Ebrahimi 10*ccdc9c3eSSadaf Ebrahimi output = "result.png" 11*ccdc9c3eSSadaf Ebrahimi 12*ccdc9c3eSSadaf Ebrahimi script = """ 13*ccdc9c3eSSadaf Ebrahimi set terminal png size 1024, 768 14*ccdc9c3eSSadaf Ebrahimi set output "{}.png" 15*ccdc9c3eSSadaf Ebrahimi set title "re2 benchlog" 16*ccdc9c3eSSadaf Ebrahimi set datafile separator ";" 17*ccdc9c3eSSadaf Ebrahimi set grid x y 18*ccdc9c3eSSadaf Ebrahimi set ylabel "MB/s" 19*ccdc9c3eSSadaf Ebrahimi set autoscale 20*ccdc9c3eSSadaf Ebrahimi plot """ 21*ccdc9c3eSSadaf Ebrahimi 22*ccdc9c3eSSadaf Ebrahimi template = """'{}' using 1:5:xticlabels(2) with linespoints linewidth 3 title "{}",\\\n""" 23*ccdc9c3eSSadaf Ebrahimi 24*ccdc9c3eSSadaf Ebrahimi benchdata = dict() 25*ccdc9c3eSSadaf Ebrahimi tempfiles = [] 26*ccdc9c3eSSadaf Ebrahimi 27*ccdc9c3eSSadaf Ebrahimi def __enter__(self): 28*ccdc9c3eSSadaf Ebrahimi return self 29*ccdc9c3eSSadaf Ebrahimi 30*ccdc9c3eSSadaf Ebrahimi def __exit__(self, type, value, traceback): 31*ccdc9c3eSSadaf Ebrahimi """ 32*ccdc9c3eSSadaf Ebrahimi remove all temporary files 33*ccdc9c3eSSadaf Ebrahimi """ 34*ccdc9c3eSSadaf Ebrahimi 35*ccdc9c3eSSadaf Ebrahimi for filename in self.tempfiles: 36*ccdc9c3eSSadaf Ebrahimi os.remove(filename) 37*ccdc9c3eSSadaf Ebrahimi 38*ccdc9c3eSSadaf Ebrahimi def parse_re2_benchlog(self, filename): 39*ccdc9c3eSSadaf Ebrahimi """ 40*ccdc9c3eSSadaf Ebrahimi parse the input benchlog and return a dictionary contain bench data 41*ccdc9c3eSSadaf Ebrahimi """ 42*ccdc9c3eSSadaf Ebrahimi 43*ccdc9c3eSSadaf Ebrahimi benchdata = self.benchdata 44*ccdc9c3eSSadaf Ebrahimi 45*ccdc9c3eSSadaf Ebrahimi with open(filename) as f: 46*ccdc9c3eSSadaf Ebrahimi 47*ccdc9c3eSSadaf Ebrahimi for raw in f.readlines(): 48*ccdc9c3eSSadaf Ebrahimi 49*ccdc9c3eSSadaf Ebrahimi data = raw.split('\t') 50*ccdc9c3eSSadaf Ebrahimi 51*ccdc9c3eSSadaf Ebrahimi if len(data) == 4: 52*ccdc9c3eSSadaf Ebrahimi 53*ccdc9c3eSSadaf Ebrahimi data = data[0].split('/') + data[1:] 54*ccdc9c3eSSadaf Ebrahimi data = list(map(str.strip, data)) 55*ccdc9c3eSSadaf Ebrahimi 56*ccdc9c3eSSadaf Ebrahimi if not benchdata.get(data[0]): 57*ccdc9c3eSSadaf Ebrahimi benchdata[data[0]] = [ data[1:] ] 58*ccdc9c3eSSadaf Ebrahimi else: 59*ccdc9c3eSSadaf Ebrahimi benchdata[data[0]].append(data[1:]) 60*ccdc9c3eSSadaf Ebrahimi 61*ccdc9c3eSSadaf Ebrahimi def gen_csv(self): 62*ccdc9c3eSSadaf Ebrahimi """ 63*ccdc9c3eSSadaf Ebrahimi generate temporary csv files 64*ccdc9c3eSSadaf Ebrahimi """ 65*ccdc9c3eSSadaf Ebrahimi 66*ccdc9c3eSSadaf Ebrahimi for name, data in self.benchdata.items(): 67*ccdc9c3eSSadaf Ebrahimi 68*ccdc9c3eSSadaf Ebrahimi with tempfile.NamedTemporaryFile(delete=False) as f: 69*ccdc9c3eSSadaf Ebrahimi 70*ccdc9c3eSSadaf Ebrahimi for index, line in enumerate(data): 71*ccdc9c3eSSadaf Ebrahimi f.write('{};{}\n'.format(index, ';'.join(line)).encode()) 72*ccdc9c3eSSadaf Ebrahimi 73*ccdc9c3eSSadaf Ebrahimi self.tempfiles.append(f.name) 74*ccdc9c3eSSadaf Ebrahimi self.script = self.script + self.template.format(f.name, name) 75*ccdc9c3eSSadaf Ebrahimi 76*ccdc9c3eSSadaf Ebrahimi def run(self): 77*ccdc9c3eSSadaf Ebrahimi self.gen_csv() 78*ccdc9c3eSSadaf Ebrahimi script = self.script[:-3].format(self.output) 79*ccdc9c3eSSadaf Ebrahimi command = subprocess.Popen(['gnuplot'], stdin=subprocess.PIPE) 80*ccdc9c3eSSadaf Ebrahimi command.communicate(script.encode()) 81*ccdc9c3eSSadaf Ebrahimi 82*ccdc9c3eSSadaf Ebrahimi 83*ccdc9c3eSSadaf Ebrahimiif __name__ == '__main__': 84*ccdc9c3eSSadaf Ebrahimi 85*ccdc9c3eSSadaf Ebrahimi parser = argparse.ArgumentParser(description='generate plots for benchlog') 86*ccdc9c3eSSadaf Ebrahimi parser.add_argument('benchlog', type=str, help='benchlog generated by re2') 87*ccdc9c3eSSadaf Ebrahimi args = parser.parse_args() 88*ccdc9c3eSSadaf Ebrahimi 89*ccdc9c3eSSadaf Ebrahimi try: 90*ccdc9c3eSSadaf Ebrahimi subprocess.Popen(['gnuplot'], stdin=subprocess.PIPE) 91*ccdc9c3eSSadaf Ebrahimi except FileNotFoundError: 92*ccdc9c3eSSadaf Ebrahimi print('you can install "gnuplot" to generate plots automatically') 93*ccdc9c3eSSadaf Ebrahimi exit(1) 94*ccdc9c3eSSadaf Ebrahimi 95*ccdc9c3eSSadaf Ebrahimi with gnuplot() as plot: 96*ccdc9c3eSSadaf Ebrahimi plot.output = args.benchlog 97*ccdc9c3eSSadaf Ebrahimi plot.parse_re2_benchlog(args.benchlog) 98*ccdc9c3eSSadaf Ebrahimi plot.run() 99