Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • benchmark/plot.py

    r76f5e9f r41a6a78  
    1414import math
    1515import numpy
     16import os
    1617import re
    1718import statistics
    1819import sys
    19 
     20import time
     21
     22import matplotlib
    2023import matplotlib.pyplot as plt
    21 from matplotlib.ticker import EngFormatter
     24from matplotlib.ticker import EngFormatter, ScalarFormatter
     25
     26def fmtDur( duration ):
     27        if duration :
     28                hours, rem = divmod(duration, 3600)
     29                minutes, rem = divmod(rem, 60)
     30                seconds, millis = divmod(rem, 1)
     31                return "%2d:%02d.%03d" % (minutes, seconds, millis * 1000)
     32        return " n/a"
    2233
    2334class Field:
    24         def __init__(self, unit, _min, _log, _name=None):
     35        def __init__(self, unit, _min, _log, _name=None, _factor=1.0):
    2536                self.unit = unit
    2637                self.min  = _min
    2738                self.log  = _log
    2839                self.name = _name
     40                self.factor = _factor
    2941
    3042field_names = {
    3143        "ns per ops"            : Field('ns'    , 0, False),
    32         "Number of processors"  : Field(''      , 1, False),
     44        "Number of processors"  : Field(''      , 1, "exact"),
    3345        "Ops per procs"         : Field('Ops'   , 0, False),
    3446        "Ops per threads"       : Field('Ops'   , 0, False),
    35         "ns per ops/procs"      : Field(''    , 0, False, _name = "Latency (ns $/$ (Processor $\\times$ Operation))" ),
     47        "ns per ops/procs"      : Field(''      , 0, False, _name = "ns $\\times$ (Processor $/$ Total Ops)" ),
    3648        "Number of threads"     : Field(''      , 1, False),
    3749        "Total Operations(ops)" : Field('Ops'   , 0, False),
    3850        "Ops/sec/procs"         : Field('Ops'   , 0, False),
    3951        "Total blocks"          : Field('Blocks', 0, False),
    40         "Ops per second"        : Field(''   , 0, False),
     52        "Ops per second"        : Field(''      , 0, False),
    4153        "Cycle size (# thrds)"  : Field('thrd'  , 1, False),
    4254        "Duration (ms)"         : Field('ms'    , 0, False),
    4355        "Target QPS"            : Field(''      , 0, False),
    4456        "Actual QPS"            : Field(''      , 0, False),
    45         "Average Read Latency"  : Field('us'    , 0, True),
    46         "Median Read Latency"   : Field('us'    , 0, True),
    47         "Tail Read Latency"     : Field('us'    , 0, True),
    48         "Average Update Latency": Field('us'    , 0, True),
    49         "Median Update Latency" : Field('us'    , 0, True),
    50         "Tail Update Latency"   : Field('us'    , 0, True),
    51         "Update Ratio"          : Field('\%'    , 0, False),
     57        "Average Read Latency"  : Field('s'     , 0, False, _factor = 0.000001),
     58        "Median Read Latency"   : Field('s'     , 0, True, _factor = 0.000001),
     59        "Tail Read Latency"     : Field('s'     , 0, True, _factor = 0.000001),
     60        "Average Update Latency": Field('s'     , 0, True, _factor = 0.000001),
     61        "Median Update Latency" : Field('s'     , 0, True, _factor = 0.000001),
     62        "Tail Update Latency"   : Field('s'     , 0, True, _factor = 0.000001),
     63        "Update Ratio"          : Field('%'   , 0, False),
     64        "Request Rate"          : Field('req/s' , 0, False),
     65        "Data Rate"             : Field('b/s'   , 0, False, _factor = 1000 * 1000, _name = "Response Throughput"),
     66        "Errors"                : Field('%'   , 0, False),
    5267}
    5368
    54 def plot(in_data, x, y, options):
     69def plot(in_data, x, y, options, prefix):
    5570        fig, ax = plt.subplots()
    56         colors = itertools.cycle(['#0095e3','#006cb4','#69df00','#0aa000','#fb0300','#e30002','#fd8f00','#ff7f00','#8f00d6','#4b009a','#ffff00','#b13f00'])
     71        colors = itertools.cycle(['#006cb4','#0aa000','#ff6600','#8510a1','#0095e3','#fd8f00','#e30002','#8f00d6','#4b009a','#ffff00','#69df00','#fb0300','#b13f00'])
    5772        series = {} # scatter data for each individual data point
    5873        groups = {} # data points for x value
     
    6277        for entry in in_data:
    6378                name = entry[0]
     79                if options.filter and not name.startswith(options.filter):
     80                        continue
     81
    6482                if not name in series:
    6583                        series[name] = {'x':[], 'y':[]}
     
    7088                if x in entry[2] and y in entry[2]:
    7189                        xval = entry[2][x]
    72                         yval = entry[2][y]
     90                        yval = entry[2][y] * field_names[y].factor
    7391                        series[name]['x'].append(xval)
    7492                        series[name]['y'].append(yval)
     
    98116        for name, data in sorted(series.items()):
    99117                _col = next(colors)
    100                 plt.scatter(data['x'], data['y'], color=_col, label=name, marker='x')
     118                plt.scatter(data['x'], data['y'], color=_col, label=name[len(prefix):], marker='x')
    101119                plt.plot(lines[name]['x'], lines[name]['min'], '--', color=_col)
    102120                plt.plot(lines[name]['x'], lines[name]['max'], '--', color=_col)
     
    119137        elif field_names[x].log:
    120138                ax.set_xscale('log')
     139                if field_names[x].log == "exact":
     140                        xvals = set()
     141                        for s in series.values():
     142                                xvals |= set(s['x'])
     143                        ax.set_xticks(sorted(xvals))
     144                        ax.get_xaxis().set_major_formatter(ScalarFormatter())
     145                        plt.xticks(rotation = 45)
    121146        else:
    122147                plt.xlim(field_names[x].min, mx + 0.25)
    123148
    124         ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
    125149        if options.logy:
    126150                ax.set_yscale('log')
     
    130154                plt.ylim(field_names[y].min, options.MaxY if options.MaxY else my*1.2)
    131155
     156        ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
     157
    132158        plt.legend(loc='upper left')
    133159
    134160        print("Results Ready")
     161        start = time.time()
    135162        if options.out:
    136163                plt.savefig(options.out, bbox_inches='tight')
    137164        else:
    138165                plt.show()
     166        end = time.time()
     167        print("Took {}".format(fmtDur(end - start)))
    139168
    140169
     
    150179        parser.add_argument('--logy', action='store_true', help="if set, makes the y-axis logscale")
    151180        parser.add_argument('--MaxY', nargs='?', type=int, help="maximum value of the y-axis")
     181        parser.add_argument('--filter', nargs='?', type=str, default="", help="if not empty, only print series that start with specified filter")
    152182
    153183        options =  parser.parse_args()
     184
     185        # if not options.out:
     186        #       matplotlib.use('SVG')
    154187
    155188        # ================================================================================
     
    173206                        fields.add(label)
    174207
     208        # filter out the series if needed
     209        if options.filter:
     210                series = set(filter(lambda elem: elem.startswith(options.filter), series))
     211
     212        # find the common prefix on series for removal (only if no filter)
     213        prefix = os.path.commonprefix(list(series))
     214
    175215        if not options.out :
    176216                print(series)
     
    193233
    194234
    195         plot(data, wantx, wanty, options)
     235        plot(data, wantx, wanty, options, prefix)
Note: See TracChangeset for help on using the changeset viewer.