summaryrefslogtreecommitdiff
path: root/report-benchmark
blob: 3b4a6fc2db69ce7dec539ebb77b5990a069f206e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/python


import ConfigParser
import glob
import os
import re
import sys
import urllib


def humantime(secs):
    units = (
        ('h', 60*60),
        ('min', 60),
        ('s', 1),
    )
    
    result = ''
    for unit, factor in units:
        if secs >= factor:
            result += '%d%s' % (int(secs / factor), unit)
            secs %= factor
    return result


def humansize(bytes):
    units = (
        ('MiB', 1024**2),
        ('KiB', 1024**1),
        ('B',   1024**0),
    )
    
    for unit, factor in units:
        if bytes >= factor:
            return '%.1f %s' % (float(bytes / factor), unit)
    return '0 B'


def humanspeed(bytes_per_second):
    bits_per_second = 8 * bytes_per_second
    factor = 1000**2
    unit = 'Mbit/s'
    return '%.1f %s' % (float(bits_per_second / factor), unit)


class Report(object):

    def __init__(self):
        self.seivots = []
        
    def load_seivot(self, filename):
        cp = ConfigParser.RawConfigParser()
        cp.read(filename)
        cp.filename = filename
        self.seivots.append(cp)
        
    def parse_revision(self, seivot):
        revstr = seivot.get('meta', 'revision')
        if ' and ' in revstr:
            obnam, larch = revstr.split(' and ')
            return int(obnam), int(larch)
        else:
            return int(revstr), 0
        
    def sort(self):
        def getkey(seivot):
            return seivot.get('meta', 'revision')
        pairs = [(getkey(seivot), seivot) for seivot in self.seivots]
        pairs.sort()
        self.seivots = [seivot for key, seivot in pairs]
        
    def groups(self, seivots):
        def getkey(seivot):
            return (seivot.get('meta', 'start-size'), 
                    seivot.get('meta', 'inc-size'))
        keys = sorted(list(set(getkey(s) for s in seivots)))
        for key in keys:
            yield [s for s in seivots if getkey(s) == key]
            
    def report(self, f):
        self.sort()
        self.preamble(f)
        for group in self.groups(self.seivots):
            self.report_group(f, group)
        self.footer(f) 

    def preamble(self, f):
        f.write('''
[[!meta title="Obnam benchmark archive"]]

Obnam+larch benchmark archive
====

This page lists results of benchmark runs of [[Obnam]],
done by <a href="http://liw.fi/">Lars Wirzenius</a>.
See [[the obnam benchmark page|benchmarkspec]]
for information on how the benchmark is set up,
and [[the result listing|benchmarks]] for individual
result. This page has summarizes results of each benchmark run,
so they can be compared.

''')
        
    def footer(self, f):
        pass
        
    def report_group(self, f, group):
        size = group[0].getint('meta', 'start-size')
        inc = group[0].getint('meta', 'inc-size')
        f.write('Size %s, increment %s\n----\n' % (humansize(size), 
                                                      humansize(inc)))
        f.write('''
<table>
<tr>
    <th>obnam</th>
    <th>larch</th>
    <th>gen0</th>
    <th>slowest inc</th>
</tr>
''')

        for seivot in group:
            obnam, larch = self.parse_revision(seivot)
            
            gen0 = self.speed(seivot, '0')
            slowest_inc = min(self.speed(seivot, gen)
                              for gen in seivot.sections()
                              if re.match(r'\d+', gen))

            f.write('<tr>\n')
            f.write('<td>%s</td>\n' % obnam)
            f.write('<td>%s</td>\n' % larch)
            f.write('<td>%s</td>\n' % humanspeed(gen0))
            f.write('<td>%s</td>\n' % humanspeed(slowest_inc))
            f.write('</tr>\n')
          
        f.write('</table>\n')

    def speed(self, seivot, gen):
        wall_clock = seivot.getfloat(gen, 'wallclock')
        new_data = seivot.getfloat(gen, 'new-data')
        return new_data / wall_clock

def main():
    r = Report()
    for filename in sys.argv[1:]:
        r.load_seivot(filename)
    r.report(sys.stdout)


if __name__ == '__main__':
    main()