Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • benchmark/plot.py

    r76f5e9f r8fca132  
    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'])
    57         series = {} # scatter data for each individual data point
    58         groups = {} # data points for x value
     71        colors  = itertools.cycle(['#006cb4','#0aa000','#ff6600','#8510a1','#0095e3','#fd8f00','#e30002','#8f00d6','#4b009a','#ffff00','#69df00','#fb0300','#b13f00'])
     72        markers = itertools.cycle(['x', '+', '1', '2', '3', '4'])
     73        series  = {} # scatter data for each individual data point
     74        groups  = {} # data points for x value
    5975
    6076        print("Preparing Data")
     
    6278        for entry in in_data:
    6379                name = entry[0]
     80                if options.filter and not name.startswith(options.filter):
     81                        continue
     82
    6483                if not name in series:
    6584                        series[name] = {'x':[], 'y':[]}
     
    7089                if x in entry[2] and y in entry[2]:
    7190                        xval = entry[2][x]
    72                         yval = entry[2][y]
     91                        yval = entry[2][y] * field_names[y].factor
    7392                        series[name]['x'].append(xval)
    7493                        series[name]['y'].append(yval)
     
    98117        for name, data in sorted(series.items()):
    99118                _col = next(colors)
    100                 plt.scatter(data['x'], data['y'], color=_col, label=name, marker='x')
    101                 plt.plot(lines[name]['x'], lines[name]['min'], '--', color=_col)
     119                _mrk = next(markers)
     120                plt.scatter(data['x'], data['y'], color=_col, label=name[len(prefix):], marker=_mrk)
     121                plt.plot(lines[name]['x'], lines[name]['min'], ':', color=_col)
    102122                plt.plot(lines[name]['x'], lines[name]['max'], '--', color=_col)
    103123                plt.plot(lines[name]['x'], lines[name]['med'], '-', color=_col)
     
    119139        elif field_names[x].log:
    120140                ax.set_xscale('log')
     141                if field_names[x].log == "exact":
     142                        xvals = set()
     143                        for s in series.values():
     144                                xvals |= set(s['x'])
     145                        ax.set_xticks(sorted(xvals))
     146                        ax.get_xaxis().set_major_formatter(ScalarFormatter())
     147                        plt.xticks(rotation = 45)
    121148        else:
    122149                plt.xlim(field_names[x].min, mx + 0.25)
    123150
    124         ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
    125151        if options.logy:
    126152                ax.set_yscale('log')
     
    130156                plt.ylim(field_names[y].min, options.MaxY if options.MaxY else my*1.2)
    131157
     158        ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
     159
    132160        plt.legend(loc='upper left')
    133161
    134162        print("Results Ready")
     163        start = time.time()
    135164        if options.out:
    136165                plt.savefig(options.out, bbox_inches='tight')
    137166        else:
    138167                plt.show()
     168        end = time.time()
     169        print("Took {}".format(fmtDur(end - start)))
    139170
    140171
     
    150181        parser.add_argument('--logy', action='store_true', help="if set, makes the y-axis logscale")
    151182        parser.add_argument('--MaxY', nargs='?', type=int, help="maximum value of the y-axis")
     183        parser.add_argument('--filter', nargs='?', type=str, default="", help="if not empty, only print series that start with specified filter")
    152184
    153185        options =  parser.parse_args()
     186
     187        # if not options.out:
     188        #       matplotlib.use('SVG')
    154189
    155190        # ================================================================================
     
    173208                        fields.add(label)
    174209
     210        # filter out the series if needed
     211        if options.filter:
     212                series = set(filter(lambda elem: elem.startswith(options.filter), series))
     213
     214        # find the common prefix on series for removal (only if no filter)
     215        prefix = os.path.commonprefix(list(series))
     216
    175217        if not options.out :
    176218                print(series)
     
    193235
    194236
    195         plot(data, wantx, wanty, options)
     237        plot(data, wantx, wanty, options, prefix)
Note: See TracChangeset for help on using the changeset viewer.