generate benchmark result files automatically

also move playground out of the benchmark suite
This commit is contained in:
ndparker 2014-02-21 22:41:08 +01:00
parent ec40a321e3
commit 647b024120
7 changed files with 337 additions and 132 deletions

View File

@ -13,11 +13,16 @@ for v in 3.4 3.3 3.2 3.1 3.0 2.7 2.6 2.5 2.4; do
set -e set -e
p=python$v p=python$v
$p make.py makefile $p make.py makefile || continue
CFLAGS=-O3 make clean compile CFLAGS=-O3 make clean compile
$p -OO bench/main.py -p >( cat - >>"$out" ) bench/*.js $p -OO bench/main.py -p >( cat - >>"$out" ) bench/*.js
) )
done done
python make.py makefile python make.py makefile
python -mbench.write -p docs/BENCHMARKS <"$out" [ "$1" = "-w" ] && \
python -mbench.write \
-p docs/BENCHMARKS \
-t docs/_userdoc/benchmark.txt \
<"$out" \
|| true

0
bench/jsmin.py Executable file → Normal file
View File

0
bench/main.py Executable file → Normal file
View File

View File

@ -28,9 +28,10 @@ Write benchmark results.
Usage:: Usage::
python -mbench.write -p plain-file <pickled python -mbench.write [-p plain] [-t table] <pickled
-p plain-file Plain file to write to (like docs/BENCHAMRKS). -p plain Plain file to write to (like docs/BENCHMARKS).
-t table Table file to write to (like docs/_userdoc/benchmark.txt).
""" """
if __doc__: if __doc__:
@ -40,9 +41,192 @@ __docformat__ = "restructuredtext en"
__license__ = "Apache License, Version 2.0" __license__ = "Apache License, Version 2.0"
__version__ = "1.0.0" __version__ = "1.0.0"
import os as _os
import re as _re
import sys as _sys import sys as _sys
try:
unicode
except NameError:
def uni(v):
if hasattr(v, 'decode'):
return v.decode('latin-1')
return str(v)
else:
def uni(v):
if isinstance(v, unicode):
return v.encode('utf-8')
return str(v)
def write_table(filename, results):
"""
Output tabled benchmark results
:Parameters:
`filename` : ``str``
Filename to write to
`results` : ``list``
Results
"""
try:
next
except NameError:
next = lambda i: (getattr(i, 'next', None) or i.__next__)()
try:
cmp
except NameError:
cmp = lambda a, b: (a > b) - (a < b)
names = [
('simple_port', 'Simple Port'),
('jsmin_2_0_9', 'jsmin 2.0.9'),
('slimit_0_8_1', 'slimit 0.8.1'),
('slimit_0_8_1_mangle', 'slimit 0.8.1 (mangle)'),
('rjsmin', '|rjsmin|'),
('_rjsmin', r'_\ |rjsmin|'),
]
benched_per_table = 2
results = sorted(results, reverse=True)
# First we transform our data into a table (list of lists)
pythons, widths = [], [0] * (benched_per_table + 1)
last_version = None
for version, _, result in results:
version = uni(version)
if not(last_version is None or version.startswith('2.')):
continue
last_version = version
namesub = _re.compile(r'(?:-\d+(?:\.\d+)*)?\.js$').sub
result = iter(result)
tables = []
# given our data it's easier to create the table transposed...
for benched in result:
rows = [['Name'] + [desc for _, desc in names]]
for _ in range(benched_per_table):
if _:
try:
benched = next(result)
except StopIteration:
rows.append([''] + ['' for _ in names])
continue
times = dict((
uni(port), (time, benched['sizes'][idx])
) for idx, (port, time) in enumerate(benched['times']))
columns = ['%s (%.1f)' % (
namesub('', _os.path.basename(uni(benched['filename']))),
benched['size'] / 1024.0,
)]
for idx, (port, _) in enumerate(names):
if port not in times:
columns.append('n/a')
continue
time, size = times[port]
if time is None:
columns.append('(failed)')
continue
columns.append('%s%.2f ms (%.1f %s)' % (
idx == 0 and ' ' or '',
time,
size / 1024.0,
idx == 0 and '\\*' or ['=', '>', '<'][
cmp(size, benched['sizes'][0])
],
))
rows.append(columns)
# calculate column widths (global for all tables)
for idx, row in enumerate(rows):
widths[idx] = max(widths[idx], max(map(len, row)))
# ... and transpose it back.
tables.append(zip(*rows))
pythons.append((version, tables))
if last_version.startswith('2.'):
break
# Second we create a rest table from it
lines = []
separator = lambda c='-': '+'.join([''] + [
c * (width + 2) for width in widths
] + [''])
for idx, (version, tables) in enumerate(pythons):
if idx:
lines.append('')
lines.append('')
line = 'Python %s' % (version,)
lines.append(line)
lines.append('~' * len(line))
for table in tables:
lines.append('')
lines.append('.. rst-class:: benchmark')
lines.append('')
for idx, row in enumerate(table):
if idx == 0:
# header
lines.append(separator())
lines.append('|'.join([''] + [
' %s%*s ' % (col, len(col) - width, '')
for width, col in zip(widths, row)
] + ['']))
lines.append(separator('='))
else: # data
lines.append('|'.join([''] + [
j == 0 and (
' %s%*s ' % (col, len(col) - widths[j], '')
) or (
['%*s ', ' %*s '][idx == 1] % (widths[j], col)
)
for j, col in enumerate(row)
] + ['']))
lines.append(separator())
fplines = []
fp = open(filename)
try:
fpiter = iter(fp)
for line in fpiter:
line = line.rstrip()
if line == '.. begin tables':
buf = []
for line in fpiter:
line = line.rstrip()
if line == '.. end tables':
fplines.append('.. begin tables')
fplines.append('')
fplines.extend(lines)
fplines.append('')
fplines.append('.. end tables')
buf = []
break
else:
buf.append(line)
else:
fplines.extend(buf)
_sys.stderr.write("Placeholder container not found!\n")
else:
fplines.append(line)
finally:
fp.close()
fp = open(filename, 'w')
try:
fp.write('\n'.join(fplines) + '\n')
finally:
fp.close()
def write_plain(filename, results): def write_plain(filename, results):
""" """
Output plain benchmark results Output plain benchmark results
@ -54,19 +238,6 @@ def write_plain(filename, results):
`results` : ``list`` `results` : ``list``
Results Results
""" """
try:
unicode
except NameError:
def uni(v):
if hasattr(v, 'decode'):
return v.decode('latin-1')
return str(v)
else:
def uni(v):
if isinstance(v, unicode):
return v.encode('utf-8')
return str(v)
lines = [] lines = []
results = sorted(results, reverse=True) results = sorted(results, reverse=True)
for idx, (version, import_notes, result) in enumerate(results): for idx, (version, import_notes, result) in enumerate(results):
@ -126,13 +297,12 @@ def write_plain(filename, results):
def main(argv=None): def main(argv=None):
""" Main """ """ Main """
import getopt as _getopt import getopt as _getopt
import os as _os
import pickle as _pickle import pickle as _pickle
if argv is None: if argv is None:
argv = _sys.argv[1:] argv = _sys.argv[1:]
try: try:
opts, args = _getopt.getopt(argv, "hp:", ["help"]) opts, args = _getopt.getopt(argv, "hp:t:", ["help"])
except getopt.GetoptError: except getopt.GetoptError:
e = _sys.exc_info()[0](_sys.exc_info()[1]) e = _sys.exc_info()[0](_sys.exc_info()[1])
print >> _sys.stderr, "%s\nTry %s -mbench.write --help" % ( print >> _sys.stderr, "%s\nTry %s -mbench.write --help" % (
@ -141,19 +311,22 @@ def main(argv=None):
) )
_sys.exit(2) _sys.exit(2)
plain = None plain, table = None, None
for key, value in opts: for key, value in opts:
if key in ("-h", "--help"): if key in ("-h", "--help"):
print >> _sys.stderr, ( print >> _sys.stderr, (
"%s -mbench.write [-p plain-file] <pickled" % ( "%s -mbench.write [-p plain] [-t table] <pickled" % (
_os.path.basename(_sys.executable), _os.path.basename(_sys.executable),
) )
) )
_sys.exit(0) _sys.exit(0)
elif key == '-p': elif key == '-p':
plain = str(value) plain = str(value)
elif key == '-t':
table = str(value)
struct = [] struct = []
_sys.stdin = getattr(_sys.stdin, 'detach', lambda: _sys.stdin)()
try: try:
while True: while True:
version, import_notes, result = _pickle.load(_sys.stdin) version, import_notes, result = _pickle.load(_sys.stdin)
@ -166,6 +339,9 @@ def main(argv=None):
if plain: if plain:
write_plain(plain, struct) write_plain(plain, struct)
if table:
write_table(table, struct)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -1,7 +1,8 @@
.. license: .. copyright:
Copyright 2011 - 2014 Copyright 2011 - 2014
André Malo or his licensors, as applicable André Malo or his licensors, as applicable
.. license:
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -21,27 +22,43 @@
rJSmin - Benchmark rJSmin - Benchmark
==================== ====================
The following numbers have been measured with the bench package The following numbers have been measured with the bench package provided
provided in the source distribution. Since the numbers don't vary much in the source distribution. Since the numbers don't vary much between
between python minor releases (e.g. 2.6 vs 2.7), only the benchmarks for python minor releases (e.g. 2.6 vs 2.7), only one benchmark per major
2.7 and 3.4 are given below. The :file:`docs/BENCHMARKS` file in the source version is given below. The :file:`docs/BENCHMARKS` file in the source
distribution contains a more complete list. distribution contains a more comprehensive list.
Here's the list of benchmarked implementations: Here's the list of benchmarked implementations:
- Simple port is the original jsmin.py port by Baruch Even **Simple port**
- jsmin 2.0.9 is a speed-refactored python port by Dave St.Germain The original jsmin.py port by Baruch Even
(it got slower since version 2.0.2 and spikes with Python 3.2 for some
reason)
- slimit 0.8.1 is a minifier based on a parse/generate-iteration. Its
Python3 support seems to be incomplete. It fails with several inputs.
- slimit 0.8.1 (mangle) is slimit 0.8.1 with name mangeling enabled
- |rjsmin| is this very project
- _\ |rjsmin| is the C reimplementation of |rjsmin|
Note that jsmin 2.0.9 and slimit produce output different from **jsmin 2.0.9**
the original jsmin.c. Also the simple port was modified to use cStringIO A speed-refactored python port by Dave St.Germain. There are some
if available (it's faster then) or io (for python 3). spikes in lower Python 3 versions (especially for the big file
[apiviewer.js]).
**slimit 0.8.1**
A minifier based on a parse/generate-iteration. Its Python3 support
seems to be incomplete as it fails with several inputs. Python2
support actually starts with Python 2.6 (name mangeling uses Python
2.6 features)
It could not be installed with Python 3.0 and Python 2.4.
**slimit 0.8.1 (mangle)**
Same as slimit 0.8.1, but with name mangeling enabled.
|**rjsmin**|
this very project
**_**\ |**rjsmin**|
The C reimplementation of |rjsmin|
Note that the various implementations produce output different from the
original jsmin.c for one reason or another. Also the simple port was
modified to use ``cStringIO`` if available (it's faster then) or io (for
python 3).
And here's a list of the benchmarked javascript files: And here's a list of the benchmarked javascript files:
@ -52,67 +69,71 @@ And here's a list of the benchmarked javascript files:
- knockout is knockout-2.0.0.js, the compressed download. - knockout is knockout-2.0.0.js, the compressed download.
- markermanager is the V3 port of the google maps markermanager. - markermanager is the V3 port of the google maps markermanager.
Inside the parentheses are size information in KiB (actually: number of Inside the parentheses are size information in KiB [#]_\. The sign
characters/1024). The sign behind the size value denotes the size difference behind the size value denotes the size difference in relation to the
in relation to the simple port (i.e. jsmin itself). simple port (i.e. jsmin itself).
.. [#] Bytes / 1024 for Python 2 and Code Points / 1024 for Python 3
.. begin tables
Python 3.4.0 Python 3.4.0
~~~~~~~~~~~~ ~~~~~~~~~~~~
.. rst-class:: benchmark .. rst-class:: benchmark
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| Name | apiviewer (953.2) | bootstrap (49.0) | | Name | apiviewer (953.2) | bootstrap (49.0) |
+=======================+=======================+======================+ +=======================+========================+======================+
| Simple Port | 2162.57 ms (951.5 \*)| 90.56 ms (26.4 \*) | | Simple Port | 2083.14 ms (951.5 \*) | 90.13 ms (26.4 \*) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| jsmin 2.0.9 | 2526.19 ms (951.5 >) | 39.41 ms (26.4 >) | | jsmin 2.0.9 | 2439.38 ms (951.5 >) | 38.70 ms (26.4 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 | n/a | n/a | | slimit 0.8.1 | (failed) | (failed) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 (mangle) | n/a | n/a | | slimit 0.8.1 (mangle) | (failed) | (failed) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| |rjsmin| | 57.31 ms (951.5 =) | 14.05 ms (26.4 >) | | |rjsmin| | 56.03 ms (951.5 =) | 13.78 ms (26.4 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| _\ |rjsmin| | 2.20 ms (951.5 =) | 0.17 ms (26.4 >) | | _\ |rjsmin| | 2.11 ms (951.5 =) | 0.17 ms (26.4 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
.. rst-class:: benchmark .. rst-class:: benchmark
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| Name | jquery (242.4) | knockout (38.9) | | Name | jquery (242.4) | knockout (38.9) |
+=======================+=======================+======================+ +=======================+========================+======================+
| Simple Port | 474.08 ms (135.9 \*)| 84.49 ms (38.6 \*) | | Simple Port | 468.94 ms (135.9 \*) | 83.92 ms (38.6 \*) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| jsmin 2.0.9 | 253.22 ms (136.8 >) | 43.57 ms (38.6 >) | | jsmin 2.0.9 | 251.12 ms (136.8 >) | 42.35 ms (38.6 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 | n/a | n/a | | slimit 0.8.1 | (failed) | (failed) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 (mangle) | n/a | n/a | | slimit 0.8.1 (mangle) | (failed) | (failed) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| |rjsmin| | 96.61 ms (135.9 =) | 2.92 ms (38.6 >) | | |rjsmin| | 95.54 ms (135.9 =) | 2.87 ms (38.6 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| _\ |rjsmin| | 1.13 ms (135.9 =) | 0.09 ms (38.6 >) | | _\ |rjsmin| | 1.12 ms (135.9 =) | 0.09 ms (38.6 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
.. rst-class:: benchmark .. rst-class:: benchmark
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| Name | markermanager (28.6) | | | Name | markermanager (28.6) | |
+=======================+=======================+======================+ +=======================+========================+======================+
| Simple Port | 45.54 ms (11.6 \*) | | | Simple Port | 44.58 ms (11.6 \*) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| jsmin 2.0.9 | 19.94 ms (11.6 >) | | | jsmin 2.0.9 | 19.18 ms (11.6 >) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 | n/a | | | slimit 0.8.1 | 149.82 ms (11.5 <) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 (mangle) | n/a | | | slimit 0.8.1 (mangle) | 174.04 ms (9.3 <) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| |rjsmin| | 5.97 ms (11.6 =) | | | |rjsmin| | 5.88 ms (11.6 =) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| _\ |rjsmin| | 0.08 ms (11.6 =) | | | _\ |rjsmin| | 0.08 ms (11.6 =) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
Python 2.7.5 Python 2.7.5
@ -120,57 +141,59 @@ Python 2.7.5
.. rst-class:: benchmark .. rst-class:: benchmark
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| Name | apiviewer (953.2) | bootstrap (49.0) | | Name | apiviewer (953.2) | bootstrap (49.0) |
+=======================+=======================+======================+ +=======================+========================+======================+
| Simple Port | 2905.73 ms (951.5 \*)| 117.53 ms (26.4 \*) | | Simple Port | 2960.91 ms (951.5 \*) | 118.82 ms (26.4 \*) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| jsmin 2.0.9 | 2996.74 ms (951.5 >) | 59.87 ms (26.4 >) | | jsmin 2.0.9 | 3087.26 ms (951.5 >) | 60.82 ms (26.4 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 | 13816.28 ms (944.3 <) | 390.69 ms (26.5 >) | | slimit 0.8.1 | 13520.48 ms (944.3 <) | 379.62 ms (26.5 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 (mangle) | 16937.11 ms (922.9 <) | 415.09 ms (22.2 <) | | slimit 0.8.1 (mangle) | 16463.29 ms (922.9 <) | 404.06 ms (22.2 <) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| |rjsmin| | 60.79 ms (951.5 =) | 16.10 ms (26.4 >) | | |rjsmin| | 60.45 ms (951.5 =) | 15.94 ms (26.4 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| _\ |rjsmin| | 2.01 ms (951.5 =) | 0.18 ms (26.4 >) | | _\ |rjsmin| | 1.92 ms (951.5 =) | 0.18 ms (26.4 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
.. rst-class:: benchmark .. rst-class:: benchmark
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| Name | jquery (242.4) | knockout (38.9) | | Name | jquery (242.4) | knockout (38.9) |
+=======================+=======================+======================+ +=======================+========================+======================+
| Simple Port | 616.05 ms (135.9 \*)| 117.73 ms (38.6 \*) | | Simple Port | 624.62 ms (135.9 \*) | 118.56 ms (38.6 \*) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| jsmin 2.0.9 | 371.60 ms (136.8 >) | 67.54 ms (38.6 >) | | jsmin 2.0.9 | 370.86 ms (136.8 >) | 67.29 ms (38.6 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 | 1849.66 ms (134.0 <) | 730.03 ms (39.0 >) | | slimit 0.8.1 | 1800.29 ms (134.0 <) | 703.96 ms (39.0 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 (mangle) | 2191.50 ms ( 95.0 <) | 866.40 ms (38.9 >) | | slimit 0.8.1 (mangle) | 2129.26 ms (95.0 <) | 844.49 ms (38.9 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| |rjsmin| | 113.46 ms (135.9 =) | 3.44 ms (38.6 >) | | |rjsmin| | 113.71 ms (135.9 =) | 3.38 ms (38.6 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| _\ |rjsmin| | 1.12 ms (135.9 =) | 0.09 ms (38.6 >) | | _\ |rjsmin| | 1.12 ms (135.9 =) | 0.09 ms (38.6 >) |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
.. rst-class:: benchmark .. rst-class:: benchmark
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| Name | markermanager (28.6) | | | Name | markermanager (28.6) | |
+=======================+=======================+======================+ +=======================+========================+======================+
| Simple Port | 58.19 ms (11.6 \*) | | | Simple Port | 59.09 ms (11.6 \*) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| jsmin 2.0.9 | 30.59 ms (11.6 >) | | | jsmin 2.0.9 | 30.78 ms (11.6 >) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 | 147.98 ms (11.5 <) | | | slimit 0.8.1 | 145.18 ms (11.5 <) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| slimit 0.8.1 (mangle) | 175.33 ms ( 9.3 <) | | | slimit 0.8.1 (mangle) | 164.81 ms (9.3 <) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| |rjsmin| | 6.99 ms (11.6 =) | | | |rjsmin| | 6.94 ms (11.6 =) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
| _\ |rjsmin| | 0.08 ms (11.6 =) | | | _\ |rjsmin| | 0.08 ms (11.6 =) | |
+-----------------------+-----------------------+----------------------+ +-----------------------+------------------------+----------------------+
.. end tables
.. vim: ft=rest tw=72 .. vim: ft=rest tw=72

View File

@ -75,3 +75,4 @@ modules = rjsmin
dist = dist =
bench bench
bench.sh

0
bench/jsmin_playground.py → playground.py Executable file → Normal file
View File