1b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#!/usr/bin/env python
2b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# -*- coding: ascii -*-
3b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangr"""
4b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang=========================
5b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang Write benchmark results
6b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang=========================
7b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
8b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei WangWrite benchmark results.
9b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
10b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang:Copyright:
11b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
12b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang Copyright 2014
13b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang Andr\xe9 Malo or his licensors, as applicable
14b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
15b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang:License:
16b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
17b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang Licensed under the Apache License, Version 2.0 (the "License");
18b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang you may not use this file except in compliance with the License.
19b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang You may obtain a copy of the License at
20b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
21b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang     http://www.apache.org/licenses/LICENSE-2.0
22b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
23b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang Unless required by applicable law or agreed to in writing, software
24b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang distributed under the License is distributed on an "AS IS" BASIS,
25b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang See the License for the specific language governing permissions and
27b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang limitations under the License.
28b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
29b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei WangUsage::
30b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
31b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    python -mbench.write [-p plain] [-t table] <pickled
32b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
33b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    -p plain  Plain file to write to (like docs/BENCHMARKS).
34b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    -t table  Table file to write to (like docs/_userdoc/benchmark.txt).
35b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
36b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang"""
37b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangif __doc__:
38b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    __doc__ = __doc__.encode('ascii').decode('unicode_escape')
39b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang__author__ = r"Andr\xe9 Malo".encode('ascii').decode('unicode_escape')
40b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang__docformat__ = "restructuredtext en"
41b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang__license__ = "Apache License, Version 2.0"
42b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang__version__ = "1.0.0"
43b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
44b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangimport os as _os
45b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangimport re as _re
46b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangimport sys as _sys
47b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
48b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
49b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangtry:
50b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    unicode
51b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangexcept NameError:
52b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def uni(v):
53b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if hasattr(v, 'decode'):
54b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            return v.decode('latin-1')
55b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        return str(v)
56b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangelse:
57b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def uni(v):
58b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if isinstance(v, unicode):
59b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            return v.encode('utf-8')
60b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        return str(v)
61b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
62b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
63b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef write_table(filename, results):
64b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
65b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    Output tabled benchmark results
66b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
67b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    :Parameters:
68b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang      `filename` : ``str``
69b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        Filename to write to
70b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
71b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang      `results` : ``list``
72b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        Results
73b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
74b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
75b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        next
76b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    except NameError:
77b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        next = lambda i: (getattr(i, 'next', None) or i.__next__)()
78b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
79b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        cmp
80b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    except NameError:
81b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        cmp = lambda a, b: (a > b) - (a < b)
82b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
83b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    names = [
84b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        ('cssmin', 'YUI Port'),
85b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        ('rcssmin', '|rcssmin|'),
86b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        ('_rcssmin', r'_\ |rcssmin|'),
87b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    ]
88b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    benched_per_table = 2
89b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
90b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    results = sorted(results, reverse=True)
91b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
92b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # First we transform our data into a table (list of lists)
93b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    pythons, widths = [], [0] * (benched_per_table + 1)
94b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    last_version = None
95b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for version, _, result in results:
96b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        version = uni(version)
97b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if not(last_version is None or version.startswith('2.')):
98b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            continue
99b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        last_version = version
100b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
101b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        namesub = _re.compile(r'(?:-\d+(?:\.\d+)*)?\.css$').sub
102b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        result = iter(result)
103b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        tables = []
104b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
105b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        # given our data it's easier to create the table transposed...
106b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        for benched in result:
107b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            rows = [['Name'] + [desc for _, desc in names]]
108b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for _ in range(benched_per_table):
109b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                if _:
110b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    try:
111b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        benched = next(result)
112b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    except StopIteration:
113b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        rows.append([''] + ['' for _ in names])
114b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        continue
115b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
116b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                times = dict((
117b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    uni(port), (time, benched['sizes'][idx])
118b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                ) for idx, (port, time) in enumerate(benched['times']))
119b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                columns = ['%s (%.1f)' % (
120b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    namesub('', _os.path.basename(uni(benched['filename']))),
121b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    benched['size'] / 1024.0,
122b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                )]
123b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                for idx, (port, _) in enumerate(names):
124b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    if port not in times:
125b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        columns.append('n/a')
126b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        continue
127b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    time, size = times[port]
128b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    if time is None:
129b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        columns.append('(failed)')
130b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        continue
131b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    columns.append('%s%.2f ms (%.1f %s)' % (
132b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        idx == 0 and ' ' or '',
133b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        time,
134b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        size / 1024.0,
135b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        idx == 0 and '\\*' or ['=', '>', '<'][
136b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                            cmp(size, benched['sizes'][0])
137b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        ],
138b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    ))
139b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                rows.append(columns)
140b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
141b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            # calculate column widths (global for all tables)
142b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for idx, row in enumerate(rows):
143b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                widths[idx] = max(widths[idx], max(map(len, row)))
144b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
145b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            # ... and transpose it back.
146b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            tables.append(zip(*rows))
147b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        pythons.append((version, tables))
148b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
149b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if last_version.startswith('2.'):
150b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            break
151b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
152b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # Second we create a rest table from it
153b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    lines = []
154b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    separator = lambda c='-': '+'.join([''] + [
155b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        c * (width + 2) for width in widths
156b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    ] + [''])
157b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
158b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for idx, (version, tables) in enumerate(pythons):
159b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if idx:
160b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            lines.append('')
161b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            lines.append('')
162b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
163b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        line = 'Python %s' % (version,)
164b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        lines.append(line)
165b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        lines.append('~' * len(line))
166b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
167b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        for table in tables:
168b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            lines.append('')
169b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            lines.append('.. rst-class:: benchmark')
170b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            lines.append('')
171b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
172b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for idx, row in enumerate(table):
173b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                if idx == 0:
174b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    # header
175b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    lines.append(separator())
176b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    lines.append('|'.join([''] + [
177b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        ' %s%*s ' % (col, len(col) - width, '')
178b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        for width, col in zip(widths, row)
179b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    ] + ['']))
180b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    lines.append(separator('='))
181b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                else: # data
182b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    lines.append('|'.join([''] + [
183b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        j == 0 and (
184b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                            ' %s%*s ' % (col, len(col) - widths[j], '')
185b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        ) or (
186b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                            ['%*s  ', ' %*s '][idx == 1] % (widths[j], col)
187b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        )
188b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        for j, col in enumerate(row)
189b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    ] + ['']))
190b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    lines.append(separator())
191b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
192b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    fplines = []
193b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    fp = open(filename)
194b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
195b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        fpiter = iter(fp)
196b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        for line in fpiter:
197b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            line = line.rstrip()
198b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            if line == '.. begin tables':
199b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                buf = []
200b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                for line in fpiter:
201b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    line = line.rstrip()
202b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    if line == '.. end tables':
203b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        fplines.append('.. begin tables')
204b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        fplines.append('')
205b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        fplines.extend(lines)
206b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        fplines.append('')
207b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        fplines.append('.. end tables')
208b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        buf = []
209b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        break
210b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    else:
211b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        buf.append(line)
212b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                else:
213b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    fplines.extend(buf)
214b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    _sys.stderr.write("Placeholder container not found!\n")
215b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            else:
216b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                fplines.append(line)
217b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    finally:
218b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        fp.close()
219b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
220b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    fp = open(filename, 'w')
221b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
222b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        fp.write('\n'.join(fplines) + '\n')
223b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    finally:
224b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        fp.close()
225b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
226b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
227b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef write_plain(filename, results):
228b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
229b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    Output plain benchmark results
230b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
231b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    :Parameters:
232b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang      `filename` : ``str``
233b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        Filename to write to
234b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
235b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang      `results` : ``list``
236b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        Results
237b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """
238b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    lines = []
239b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    results = sorted(results, reverse=True)
240b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for idx, (version, import_notes, result) in enumerate(results):
241b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if idx:
242b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            lines.append('')
243b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            lines.append('')
244b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
245b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        lines.append('$ python%s -OO bench/main.py bench/*.css' % (
246b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            '.'.join(version.split('.')[:2])
247b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        ))
248b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        lines.append('~' * 72)
249b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        for note in import_notes:
250b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            lines.append(uni(note))
251b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        lines.append('Python Release: %s' % (version,))
252b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
253b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        for single in result:
254b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            lines.append('')
255b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            lines.append('Benchmarking %r... (%.1f KiB)' % (
256b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                uni(single['filename']), single['size'] / 1024.0
257b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            ))
258b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for msg in single['messages']:
259b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                lines.append(msg)
260b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            times = []
261b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            space = max([len(uni(port)) for port, _ in single['times']])
262b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            for idx, (port, time) in enumerate(single['times']):
263b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                port = uni(port)
264b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                if time is None:
265b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    lines.append("  FAILED %s" % (port,))
266b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                else:
267b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    times.append(time)
268b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    lines.append(
269b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        "  Timing %s%s ... (%5.1f KiB %s) %8.2f ms" % (
270b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                            port,
271b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                            " " * (space - len(port)),
272b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                            single['sizes'][idx] / 1024.0,
273b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                            idx == 0 and '*' or ['=', '>', '<'][
274b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                                cmp(single['sizes'][idx], single['sizes'][0])
275b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                            ],
276b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                            time
277b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        )
278b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    )
279b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    if len(times) > 1:
280b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        lines[-1] += " (factor: %s)" % (', '.join([
281b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                            '%.2f' % (timed / time) for timed in times[:-1]
282b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        ]))
283b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
284b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    lines.append('')
285b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    lines.append('')
286b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    lines.append('# vim: nowrap')
287b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    fp = open(filename, 'w')
288b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
289b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        fp.write('\n'.join(lines) + '\n')
290b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    finally:
291b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        fp.close()
292b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
293b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
294b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef main(argv=None):
295b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Main """
296b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    import getopt as _getopt
297b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    import pickle as _pickle
298b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
299b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if argv is None:
300b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        argv = _sys.argv[1:]
301b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
302b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        opts, args = _getopt.getopt(argv, "hp:t:", ["help"])
303b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    except getopt.GetoptError:
304b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        e = _sys.exc_info()[0](_sys.exc_info()[1])
305b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        print >> _sys.stderr, "%s\nTry %s -mbench.write --help" % (
306b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            e,
307b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            _os.path.basename(_sys.executable),
308b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        )
309b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        _sys.exit(2)
310b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
311b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    plain, table = None, None
312b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    for key, value in opts:
313b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        if key in ("-h", "--help"):
314b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            print >> _sys.stderr, (
315b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                "%s -mbench.write [-p plain] [-t table] <pickled" % (
316b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    _os.path.basename(_sys.executable),
317b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                )
318b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            )
319b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            _sys.exit(0)
320b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        elif key == '-p':
321b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            plain = str(value)
322b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        elif key == '-t':
323b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            table = str(value)
324b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
325b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    struct = []
326b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    _sys.stdin = getattr(_sys.stdin, 'detach', lambda: _sys.stdin)()
327b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    try:
328b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        while True:
329b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            version, import_notes, result = _pickle.load(_sys.stdin)
330b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            if hasattr(version, 'decode'):
331b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                version = version.decode('latin-1')
332b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            struct.append((version, import_notes, result))
333b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    except EOFError:
334b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        pass
335b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
336b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if plain:
337b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        write_plain(plain, struct)
338b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
339b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if table:
340b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        write_table(table, struct)
341b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
342b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
343b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangif __name__ == '__main__':
344b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    main()
345