Permalink
Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
136 lines (105 sloc) 3.44 KB
# coding: utf-8
"""
Speed tests
-----------
Note: this file is not named test_*.py as it is not part of the
test suite ran by pytest.
:copyright: (c) 2012 by Simon Sapin.
:license: BSD, see LICENSE for more details.
"""
from __future__ import division, unicode_literals
import contextlib
import functools
import os.path
import sys
import timeit
from cssutils import parseString
from .. import tokenizer
from ..css21 import CSS21Parser
from ..parsing import remove_whitespace
CSS_REPEAT = 4
TIMEIT_REPEAT = 3
TIMEIT_NUMBER = 20
def load_css():
filename = os.path.join(os.path.dirname(__file__),
'..', '..', 'docs', '_static', 'custom.css')
with open(filename, 'rb') as fd:
return b'\n'.join([fd.read()] * CSS_REPEAT)
# Pre-load so that I/O is not measured
CSS = load_css()
@contextlib.contextmanager
def install_tokenizer(name):
original = tokenizer.tokenize_flat
try:
tokenizer.tokenize_flat = getattr(tokenizer, name)
yield
finally:
tokenizer.tokenize_flat = original
def parse(tokenizer_name):
with install_tokenizer(tokenizer_name):
stylesheet = CSS21Parser().parse_stylesheet_bytes(CSS)
result = []
for rule in stylesheet.rules:
selector = rule.selector.as_css()
declarations = [
(declaration.name, len(list(remove_whitespace(declaration.value))))
for declaration in rule.declarations]
result.append((selector, declarations))
return result
parse_cython = functools.partial(parse, 'cython_tokenize_flat')
parse_python = functools.partial(parse, 'python_tokenize_flat')
def parse_cssutils():
stylesheet = parseString(CSS)
result = []
for rule in stylesheet.cssRules:
selector = rule.selectorText
declarations = [
(declaration.name, len(list(declaration.propertyValue)))
for declaration in rule.style.getProperties(all=True)]
result.append((selector, declarations))
return result
def check_consistency():
result = parse_python()
assert len(result) > 0
if tokenizer.cython_tokenize_flat:
assert parse_cython() == result
assert parse_cssutils() == result
version = '.'.join(map(str, sys.version_info[:3]))
print('Python {}, consistency OK.'.format(version))
def warm_up():
is_pypy = hasattr(sys, 'pypy_translation_info')
if is_pypy:
print('Warming up for PyPy...')
for i in range(80):
for i in range(10):
parse_python()
parse_cssutils()
sys.stdout.write('.')
sys.stdout.flush()
sys.stdout.write('\n')
def time(function):
seconds = timeit.Timer(function).repeat(TIMEIT_REPEAT, TIMEIT_NUMBER)
miliseconds = int(min(seconds) * 1000)
return miliseconds
def run():
if tokenizer.cython_tokenize_flat:
data_set = [
('tinycss + speedups ', parse_cython),
]
else:
print('Speedups are NOT available.')
data_set = []
data_set += [
('tinycss WITHOUT speedups', parse_python),
('cssutils ', parse_cssutils),
]
label, function = data_set.pop(0)
ref = time(function)
print('{} {} ms'.format(label, ref))
for label, function in data_set:
result = time(function)
print('{} {} ms {:.2f}x'.format(label, result, result / ref))
if __name__ == '__main__':
check_consistency()
warm_up()
run()