|
rpm-build |
d9acb6 |
import sys, re, string, time, copy, gc
|
|
rpm-build |
d9acb6 |
from itertools import *
|
|
rpm-build |
d9acb6 |
import time
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
izip
|
|
rpm-build |
d9acb6 |
except NameError:
|
|
rpm-build |
d9acb6 |
izip = zip # Py3
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def exec_(code, glob):
|
|
rpm-build |
d9acb6 |
if sys.version_info[0] >= 3:
|
|
rpm-build |
d9acb6 |
exec(code, glob)
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
exec("exec code in glob")
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
TREE_FACTOR = 1 # increase tree size with '-l / '-L' cmd option
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
_TEXT = "some ASCII text" * TREE_FACTOR
|
|
rpm-build |
d9acb6 |
_UTEXT = u"some klingon: \F8D2" * TREE_FACTOR
|
|
rpm-build |
d9acb6 |
_ATTRIBUTES = {
|
|
rpm-build |
d9acb6 |
'{attr}test1' : _TEXT,
|
|
rpm-build |
d9acb6 |
'{attr}test2' : _TEXT,
|
|
rpm-build |
d9acb6 |
'bla1' : _TEXT,
|
|
rpm-build |
d9acb6 |
'bla2' : _TEXT,
|
|
rpm-build |
d9acb6 |
'bla3' : _TEXT
|
|
rpm-build |
d9acb6 |
}
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def initArgs(argv):
|
|
rpm-build |
d9acb6 |
global TREE_FACTOR
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
argv.remove('-l')
|
|
rpm-build |
d9acb6 |
# use large trees
|
|
rpm-build |
d9acb6 |
TREE_FACTOR *= 2
|
|
rpm-build |
d9acb6 |
except ValueError:
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
argv.remove('-L')
|
|
rpm-build |
d9acb6 |
# use LARGE trees
|
|
rpm-build |
d9acb6 |
TREE_FACTOR *= 2
|
|
rpm-build |
d9acb6 |
except ValueError:
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
############################################################
|
|
rpm-build |
d9acb6 |
# benchmark decorators
|
|
rpm-build |
d9acb6 |
############################################################
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def with_attributes(*use_attributes):
|
|
rpm-build |
d9acb6 |
"Decorator for benchmarks that use attributes"
|
|
rpm-build |
d9acb6 |
vmap = {False : 0, True : 1}
|
|
rpm-build |
d9acb6 |
values = [ vmap[bool(v)] for v in use_attributes ]
|
|
rpm-build |
d9acb6 |
def set_value(function):
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
function.ATTRIBUTES.update(values)
|
|
rpm-build |
d9acb6 |
except AttributeError:
|
|
rpm-build |
d9acb6 |
function.ATTRIBUTES = set(values)
|
|
rpm-build |
d9acb6 |
return function
|
|
rpm-build |
d9acb6 |
return set_value
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def with_text(no_text=False, text=False, utext=False):
|
|
rpm-build |
d9acb6 |
"Decorator for benchmarks that use text"
|
|
rpm-build |
d9acb6 |
values = []
|
|
rpm-build |
d9acb6 |
if no_text:
|
|
rpm-build |
d9acb6 |
values.append(0)
|
|
rpm-build |
d9acb6 |
if text:
|
|
rpm-build |
d9acb6 |
values.append(1)
|
|
rpm-build |
d9acb6 |
if utext:
|
|
rpm-build |
d9acb6 |
values.append(2)
|
|
rpm-build |
d9acb6 |
def set_value(function):
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
function.TEXT.add(values)
|
|
rpm-build |
d9acb6 |
except AttributeError:
|
|
rpm-build |
d9acb6 |
function.TEXT = set(values)
|
|
rpm-build |
d9acb6 |
return function
|
|
rpm-build |
d9acb6 |
return set_value
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def onlylib(*libs):
|
|
rpm-build |
d9acb6 |
"Decorator to restrict benchmarks to specific libraries"
|
|
rpm-build |
d9acb6 |
def set_libs(function):
|
|
rpm-build |
d9acb6 |
if libs:
|
|
rpm-build |
d9acb6 |
function.LIBS = libs
|
|
rpm-build |
d9acb6 |
return function
|
|
rpm-build |
d9acb6 |
return set_libs
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def serialized(function):
|
|
rpm-build |
d9acb6 |
"Decorator for benchmarks that require serialized XML data"
|
|
rpm-build |
d9acb6 |
function.STRING = True
|
|
rpm-build |
d9acb6 |
return function
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def children(function):
|
|
rpm-build |
d9acb6 |
"Decorator for benchmarks that require a list of root children"
|
|
rpm-build |
d9acb6 |
function.CHILDREN = True
|
|
rpm-build |
d9acb6 |
return function
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def nochange(function):
|
|
rpm-build |
d9acb6 |
"Decorator for benchmarks that do not change the XML tree"
|
|
rpm-build |
d9acb6 |
function.NO_CHANGE = True
|
|
rpm-build |
d9acb6 |
return function
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
############################################################
|
|
rpm-build |
d9acb6 |
# benchmark baseclass
|
|
rpm-build |
d9acb6 |
############################################################
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
class SkippedTest(Exception):
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
class TreeBenchMark(object):
|
|
rpm-build |
d9acb6 |
atoz = string.ascii_lowercase
|
|
rpm-build |
d9acb6 |
repeat100 = range(100)
|
|
rpm-build |
d9acb6 |
repeat500 = range(500)
|
|
rpm-build |
d9acb6 |
repeat1000 = range(1000)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
_LIB_NAME_MAP = {
|
|
rpm-build |
d9acb6 |
'etree' : 'lxe',
|
|
rpm-build |
d9acb6 |
'ElementTree' : 'ET',
|
|
rpm-build |
d9acb6 |
'cElementTree' : 'cET'
|
|
rpm-build |
d9acb6 |
}
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
SEARCH_TAG = "{cdefg}a00001"
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def __init__(self, etree, etree_parser=None):
|
|
rpm-build |
d9acb6 |
self.etree = etree
|
|
rpm-build |
d9acb6 |
libname = etree.__name__.split('.')[-1]
|
|
rpm-build |
d9acb6 |
self.lib_name = self._LIB_NAME_MAP.get(libname, libname)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
if libname == 'etree':
|
|
rpm-build |
d9acb6 |
deepcopy = copy.deepcopy
|
|
rpm-build |
d9acb6 |
def set_property(root, fname):
|
|
rpm-build |
d9acb6 |
xml = self._serialize_tree(root)
|
|
rpm-build |
d9acb6 |
if etree_parser is not None:
|
|
rpm-build |
d9acb6 |
setattr(self, fname, lambda : etree.XML(xml, etree_parser))
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
setattr(self, fname, lambda : deepcopy(root))
|
|
rpm-build |
d9acb6 |
setattr(self, fname + '_xml', lambda : xml)
|
|
rpm-build |
d9acb6 |
setattr(self, fname + '_children', lambda : root[:])
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
def set_property(root, fname):
|
|
rpm-build |
d9acb6 |
setattr(self, fname, self.et_make_clone_factory(root))
|
|
rpm-build |
d9acb6 |
xml = self._serialize_tree(root)
|
|
rpm-build |
d9acb6 |
setattr(self, fname + '_xml', lambda : xml)
|
|
rpm-build |
d9acb6 |
setattr(self, fname + '_children', lambda : root[:])
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
attribute_list = list(enumerate( [{}, _ATTRIBUTES] ))
|
|
rpm-build |
d9acb6 |
text_list = list(enumerate( [None, _TEXT, _UTEXT] ))
|
|
rpm-build |
d9acb6 |
build_name = self._tree_builder_name
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
self.setup_times = []
|
|
rpm-build |
d9acb6 |
for tree in self._all_trees():
|
|
rpm-build |
d9acb6 |
times = []
|
|
rpm-build |
d9acb6 |
self.setup_times.append(times)
|
|
rpm-build |
d9acb6 |
setup = getattr(self, '_setup_tree%d' % tree)
|
|
rpm-build |
d9acb6 |
for an, attributes in attribute_list:
|
|
rpm-build |
d9acb6 |
for tn, text in text_list:
|
|
rpm-build |
d9acb6 |
root, t = setup(text, attributes)
|
|
rpm-build |
d9acb6 |
times.append(t)
|
|
rpm-build |
d9acb6 |
set_property(root, build_name(tree, tn, an))
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def _tree_builder_name(self, tree, tn, an):
|
|
rpm-build |
d9acb6 |
return '_root%d_T%d_A%d' % (tree, tn, an)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def tree_builder(self, tree, tn, an, serial, children):
|
|
rpm-build |
d9acb6 |
name = self._tree_builder_name(tree, tn, an)
|
|
rpm-build |
d9acb6 |
if serial:
|
|
rpm-build |
d9acb6 |
name += '_xml'
|
|
rpm-build |
d9acb6 |
elif children:
|
|
rpm-build |
d9acb6 |
name += '_children'
|
|
rpm-build |
d9acb6 |
return getattr(self, name)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def _serialize_tree(self, root):
|
|
rpm-build |
d9acb6 |
return self.etree.tostring(root, encoding='UTF-8')
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def et_make_clone_factory(self, elem):
|
|
rpm-build |
d9acb6 |
def generate_elem(append, elem, level):
|
|
rpm-build |
d9acb6 |
var = "e" + str(level)
|
|
rpm-build |
d9acb6 |
arg = repr(elem.tag)
|
|
rpm-build |
d9acb6 |
if elem.attrib:
|
|
rpm-build |
d9acb6 |
arg += ", **%r" % elem.attrib
|
|
rpm-build |
d9acb6 |
if level == 1:
|
|
rpm-build |
d9acb6 |
append(" e1 = Element(%s)" % arg)
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
append(" %s = SubElement(e%d, %s)" % (var, level-1, arg))
|
|
rpm-build |
d9acb6 |
if elem.text:
|
|
rpm-build |
d9acb6 |
append(" %s.text = %r" % (var, elem.text))
|
|
rpm-build |
d9acb6 |
if elem.tail:
|
|
rpm-build |
d9acb6 |
append(" %s.tail = %r" % (var, elem.tail))
|
|
rpm-build |
d9acb6 |
for e in elem:
|
|
rpm-build |
d9acb6 |
generate_elem(append, e, level+1)
|
|
rpm-build |
d9acb6 |
# generate code for a function that creates a tree
|
|
rpm-build |
d9acb6 |
output = ["def element_factory():"]
|
|
rpm-build |
d9acb6 |
generate_elem(output.append, elem, 1)
|
|
rpm-build |
d9acb6 |
output.append(" return e1")
|
|
rpm-build |
d9acb6 |
# setup global function namespace
|
|
rpm-build |
d9acb6 |
namespace = {
|
|
rpm-build |
d9acb6 |
"Element" : self.etree.Element,
|
|
rpm-build |
d9acb6 |
"SubElement" : self.etree.SubElement
|
|
rpm-build |
d9acb6 |
}
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
# create function object
|
|
rpm-build |
d9acb6 |
exec_("\n".join(output), namespace)
|
|
rpm-build |
d9acb6 |
return namespace["element_factory"]
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def _all_trees(self):
|
|
rpm-build |
d9acb6 |
all_trees = []
|
|
rpm-build |
d9acb6 |
for name in dir(self):
|
|
rpm-build |
d9acb6 |
if name.startswith('_setup_tree'):
|
|
rpm-build |
d9acb6 |
all_trees.append(int(name[11:]))
|
|
rpm-build |
d9acb6 |
return all_trees
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def _setup_tree1(self, text, attributes):
|
|
rpm-build |
d9acb6 |
"tree with 26 2nd level and 520 * TREE_FACTOR 3rd level children"
|
|
rpm-build |
d9acb6 |
atoz = self.atoz
|
|
rpm-build |
d9acb6 |
SubElement = self.etree.SubElement
|
|
rpm-build |
d9acb6 |
current_time = time.time
|
|
rpm-build |
d9acb6 |
t = current_time()
|
|
rpm-build |
d9acb6 |
root = self.etree.Element('{abc}rootnode')
|
|
rpm-build |
d9acb6 |
for ch1 in atoz:
|
|
rpm-build |
d9acb6 |
el = SubElement(root, "{abc}"+ch1*5, attributes)
|
|
rpm-build |
d9acb6 |
el.text = text
|
|
rpm-build |
d9acb6 |
for ch2 in atoz:
|
|
rpm-build |
d9acb6 |
tag = "{cdefg}%s00001" % ch2
|
|
rpm-build |
d9acb6 |
for i in range(20 * TREE_FACTOR):
|
|
rpm-build |
d9acb6 |
SubElement(el, tag).tail = text
|
|
rpm-build |
d9acb6 |
t = current_time() - t
|
|
rpm-build |
d9acb6 |
return (root, t)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def _setup_tree2(self, text, attributes):
|
|
rpm-build |
d9acb6 |
"tree with 520 * TREE_FACTOR 2nd level and 26 3rd level children"
|
|
rpm-build |
d9acb6 |
atoz = self.atoz
|
|
rpm-build |
d9acb6 |
SubElement = self.etree.SubElement
|
|
rpm-build |
d9acb6 |
current_time = time.time
|
|
rpm-build |
d9acb6 |
t = current_time()
|
|
rpm-build |
d9acb6 |
root = self.etree.Element('{abc}rootnode')
|
|
rpm-build |
d9acb6 |
for ch1 in atoz:
|
|
rpm-build |
d9acb6 |
for i in range(20 * TREE_FACTOR):
|
|
rpm-build |
d9acb6 |
el = SubElement(root, "{abc}"+ch1*5, attributes)
|
|
rpm-build |
d9acb6 |
el.text = text
|
|
rpm-build |
d9acb6 |
for ch2 in atoz:
|
|
rpm-build |
d9acb6 |
SubElement(el, "{cdefg}%s00001" % ch2).tail = text
|
|
rpm-build |
d9acb6 |
t = current_time() - t
|
|
rpm-build |
d9acb6 |
return (root, t)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def _setup_tree3(self, text, attributes):
|
|
rpm-build |
d9acb6 |
"tree of depth 8 + TREE_FACTOR with 3 children per node"
|
|
rpm-build |
d9acb6 |
SubElement = self.etree.SubElement
|
|
rpm-build |
d9acb6 |
current_time = time.time
|
|
rpm-build |
d9acb6 |
t = current_time()
|
|
rpm-build |
d9acb6 |
root = self.etree.Element('{abc}rootnode')
|
|
rpm-build |
d9acb6 |
children = [root]
|
|
rpm-build |
d9acb6 |
for i in range(6 + TREE_FACTOR):
|
|
rpm-build |
d9acb6 |
children = [ SubElement(c, "{cdefg}a%05d" % (i%8), attributes)
|
|
rpm-build |
d9acb6 |
for i,c in enumerate(chain(children, children, children)) ]
|
|
rpm-build |
d9acb6 |
for child in children:
|
|
rpm-build |
d9acb6 |
child.text = text
|
|
rpm-build |
d9acb6 |
child.tail = text
|
|
rpm-build |
d9acb6 |
t = current_time() - t
|
|
rpm-build |
d9acb6 |
return (root, t)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def _setup_tree4(self, text, attributes):
|
|
rpm-build |
d9acb6 |
"small tree with 26 2nd level and 2 3rd level children"
|
|
rpm-build |
d9acb6 |
SubElement = self.etree.SubElement
|
|
rpm-build |
d9acb6 |
current_time = time.time
|
|
rpm-build |
d9acb6 |
t = current_time()
|
|
rpm-build |
d9acb6 |
root = self.etree.Element('{abc}rootnode')
|
|
rpm-build |
d9acb6 |
for ch1 in self.atoz:
|
|
rpm-build |
d9acb6 |
el = SubElement(root, "{abc}"+ch1*5, attributes)
|
|
rpm-build |
d9acb6 |
el.text = text
|
|
rpm-build |
d9acb6 |
SubElement(el, "{cdefg}a00001", attributes).tail = text
|
|
rpm-build |
d9acb6 |
SubElement(el, "{cdefg}z00000", attributes).tail = text
|
|
rpm-build |
d9acb6 |
t = current_time() - t
|
|
rpm-build |
d9acb6 |
return (root, t)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def benchmarks(self):
|
|
rpm-build |
d9acb6 |
"""Returns a list of all benchmarks.
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
A benchmark is a tuple containing a method name and a list of tree
|
|
rpm-build |
d9acb6 |
numbers. Trees are prepared by the setup function.
|
|
rpm-build |
d9acb6 |
"""
|
|
rpm-build |
d9acb6 |
all_trees = self._all_trees()
|
|
rpm-build |
d9acb6 |
benchmarks = []
|
|
rpm-build |
d9acb6 |
for name in dir(self):
|
|
rpm-build |
d9acb6 |
if not name.startswith('bench_'):
|
|
rpm-build |
d9acb6 |
continue
|
|
rpm-build |
d9acb6 |
method = getattr(self, name)
|
|
rpm-build |
d9acb6 |
if hasattr(method, 'LIBS') and self.lib_name not in method.LIBS:
|
|
rpm-build |
d9acb6 |
method_call = None
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
method_call = method
|
|
rpm-build |
d9acb6 |
if method.__doc__:
|
|
rpm-build |
d9acb6 |
tree_sets = method.__doc__.split()
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
tree_sets = ()
|
|
rpm-build |
d9acb6 |
if tree_sets:
|
|
rpm-build |
d9acb6 |
tree_tuples = [list(map(int, tree_set.split(',')))
|
|
rpm-build |
d9acb6 |
for tree_set in tree_sets]
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
arg_count = method.func_code.co_argcount - 1
|
|
rpm-build |
d9acb6 |
except AttributeError:
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
arg_count = method.__code__.co_argcount - 1
|
|
rpm-build |
d9acb6 |
except AttributeError:
|
|
rpm-build |
d9acb6 |
arg_count = 1
|
|
rpm-build |
d9acb6 |
tree_tuples = self._permutations(all_trees, arg_count)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
serialized = getattr(method, 'STRING', False)
|
|
rpm-build |
d9acb6 |
children = getattr(method, 'CHILDREN', False)
|
|
rpm-build |
d9acb6 |
no_change = getattr(method, 'NO_CHANGE', False)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
for tree_tuple in tree_tuples:
|
|
rpm-build |
d9acb6 |
for tn in sorted(getattr(method, 'TEXT', (0,))):
|
|
rpm-build |
d9acb6 |
for an in sorted(getattr(method, 'ATTRIBUTES', (0,))):
|
|
rpm-build |
d9acb6 |
benchmarks.append((name, method_call, tree_tuple,
|
|
rpm-build |
d9acb6 |
tn, an, serialized, children,
|
|
rpm-build |
d9acb6 |
no_change))
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
return benchmarks
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def _permutations(self, seq, count):
|
|
rpm-build |
d9acb6 |
def _permutations(prefix, remainder, count):
|
|
rpm-build |
d9acb6 |
if count == 0:
|
|
rpm-build |
d9acb6 |
return [ prefix[:] ]
|
|
rpm-build |
d9acb6 |
count -= 1
|
|
rpm-build |
d9acb6 |
perms = []
|
|
rpm-build |
d9acb6 |
prefix.append(None)
|
|
rpm-build |
d9acb6 |
for pos, el in enumerate(remainder):
|
|
rpm-build |
d9acb6 |
new_remainder = remainder[:pos] + remainder[pos+1:]
|
|
rpm-build |
d9acb6 |
prefix[-1] = el
|
|
rpm-build |
d9acb6 |
perms.extend( _permutations(prefix, new_remainder, count) )
|
|
rpm-build |
d9acb6 |
prefix.pop()
|
|
rpm-build |
d9acb6 |
return perms
|
|
rpm-build |
d9acb6 |
return _permutations([], seq, count)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
############################################################
|
|
rpm-build |
d9acb6 |
# Prepare and run benchmark suites
|
|
rpm-build |
d9acb6 |
############################################################
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def buildSuites(benchmark_class, etrees, selected):
|
|
rpm-build |
d9acb6 |
benchmark_suites = list(map(benchmark_class, etrees))
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
# sorted by name and tree tuple
|
|
rpm-build |
d9acb6 |
benchmarks = [ sorted(b.benchmarks()) for b in benchmark_suites ]
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
selected = [ re.compile(r).search for r in selected ]
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
if selected:
|
|
rpm-build |
d9acb6 |
benchmarks = [ [ b for b in bs
|
|
rpm-build |
d9acb6 |
if [ match for match in selected
|
|
rpm-build |
d9acb6 |
if match(b[0]) ] ]
|
|
rpm-build |
d9acb6 |
for bs in benchmarks ]
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
return (benchmark_suites, benchmarks)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def build_treeset_name(trees, tn, an, serialized, children):
|
|
rpm-build |
d9acb6 |
text = {0:'-', 1:'S', 2:'U'}[tn]
|
|
rpm-build |
d9acb6 |
attr = {0:'-', 1:'A'}[an]
|
|
rpm-build |
d9acb6 |
ser = {True:'X', False:'T'}[serialized]
|
|
rpm-build |
d9acb6 |
chd = {True:'C', False:'R'}[children]
|
|
rpm-build |
d9acb6 |
return "%s%s%s%s T%s" % (text, attr, ser, chd, ',T'.join(map(str, trees))[:6])
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def printSetupTimes(benchmark_suites):
|
|
rpm-build |
d9acb6 |
print("Setup times for trees in seconds:")
|
|
rpm-build |
d9acb6 |
for b in benchmark_suites:
|
|
rpm-build |
d9acb6 |
sys.stdout.write("%-3s: " % b.lib_name)
|
|
rpm-build |
d9acb6 |
for an in (0,1):
|
|
rpm-build |
d9acb6 |
for tn in (0,1,2):
|
|
rpm-build |
d9acb6 |
sys.stdout.write(' %s ' %
|
|
rpm-build |
d9acb6 |
build_treeset_name((), tn, an, False, False)[:2])
|
|
rpm-build |
d9acb6 |
print('')
|
|
rpm-build |
d9acb6 |
for i, tree_times in enumerate(b.setup_times):
|
|
rpm-build |
d9acb6 |
print(" T%d: %s" % (i+1, ' '.join("%6.4f" % t for t in tree_times)))
|
|
rpm-build |
d9acb6 |
print('')
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def runBench(suite, method_name, method_call, tree_set, tn, an,
|
|
rpm-build |
d9acb6 |
serial, children, no_change):
|
|
rpm-build |
d9acb6 |
if method_call is None:
|
|
rpm-build |
d9acb6 |
raise SkippedTest
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
current_time = time.time
|
|
rpm-build |
d9acb6 |
call_repeat = range(10)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
tree_builders = [ suite.tree_builder(tree, tn, an, serial, children)
|
|
rpm-build |
d9acb6 |
for tree in tree_set ]
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
rebuild_trees = not no_change and not serial
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
args = tuple([ build() for build in tree_builders ])
|
|
rpm-build |
d9acb6 |
method_call(*args) # run once to skip setup overhead
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
times = []
|
|
rpm-build |
d9acb6 |
for i in range(3):
|
|
rpm-build |
d9acb6 |
gc.collect()
|
|
rpm-build |
d9acb6 |
gc.disable()
|
|
rpm-build |
d9acb6 |
t = -1
|
|
rpm-build |
d9acb6 |
for i in call_repeat:
|
|
rpm-build |
d9acb6 |
if rebuild_trees:
|
|
rpm-build |
d9acb6 |
args = [ build() for build in tree_builders ]
|
|
rpm-build |
d9acb6 |
t_one_call = current_time()
|
|
rpm-build |
d9acb6 |
method_call(*args)
|
|
rpm-build |
d9acb6 |
t_one_call = current_time() - t_one_call
|
|
rpm-build |
d9acb6 |
if t < 0:
|
|
rpm-build |
d9acb6 |
t = t_one_call
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
t = min(t, t_one_call)
|
|
rpm-build |
d9acb6 |
times.append(1000.0 * t)
|
|
rpm-build |
d9acb6 |
gc.enable()
|
|
rpm-build |
d9acb6 |
if rebuild_trees:
|
|
rpm-build |
d9acb6 |
args = ()
|
|
rpm-build |
d9acb6 |
args = ()
|
|
rpm-build |
d9acb6 |
gc.collect()
|
|
rpm-build |
d9acb6 |
return times
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def runBenchmarks(benchmark_suites, benchmarks):
|
|
rpm-build |
d9acb6 |
for bench_calls in izip(*benchmarks):
|
|
rpm-build |
d9acb6 |
for lib, (bench, benchmark_setup) in enumerate(izip(benchmark_suites, bench_calls)):
|
|
rpm-build |
d9acb6 |
bench_name = benchmark_setup[0]
|
|
rpm-build |
d9acb6 |
tree_set_name = build_treeset_name(*benchmark_setup[-6:-1])
|
|
rpm-build |
d9acb6 |
sys.stdout.write("%-3s: %-28s (%-10s) " % (
|
|
rpm-build |
d9acb6 |
bench.lib_name, bench_name[6:34], tree_set_name))
|
|
rpm-build |
d9acb6 |
sys.stdout.flush()
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
result = runBench(bench, *benchmark_setup)
|
|
rpm-build |
d9acb6 |
except SkippedTest:
|
|
rpm-build |
d9acb6 |
print("skipped")
|
|
rpm-build |
d9acb6 |
except KeyboardInterrupt:
|
|
rpm-build |
d9acb6 |
print("interrupted by user")
|
|
rpm-build |
d9acb6 |
sys.exit(1)
|
|
rpm-build |
d9acb6 |
except Exception:
|
|
rpm-build |
d9acb6 |
exc_type, exc_value = sys.exc_info()[:2]
|
|
rpm-build |
d9acb6 |
print("failed: %s: %s" % (exc_type.__name__, exc_value))
|
|
rpm-build |
d9acb6 |
exc_type = exc_value = None
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
print("%9.4f msec/pass, best of (%s)" % (
|
|
rpm-build |
d9acb6 |
min(result), ' '.join("%9.4f" % t for t in result)))
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
if len(benchmark_suites) > 1:
|
|
rpm-build |
d9acb6 |
print('') # empty line between different benchmarks
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
############################################################
|
|
rpm-build |
d9acb6 |
# Main program
|
|
rpm-build |
d9acb6 |
############################################################
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def main(benchmark_class):
|
|
rpm-build |
d9acb6 |
import_lxml = True
|
|
rpm-build |
d9acb6 |
callgrind_zero = False
|
|
rpm-build |
d9acb6 |
if len(sys.argv) > 1:
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
sys.argv.remove('-i')
|
|
rpm-build |
d9acb6 |
# run benchmark 'inplace'
|
|
rpm-build |
d9acb6 |
sys.path.insert(0, 'src')
|
|
rpm-build |
d9acb6 |
except ValueError:
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
sys.argv.remove('-nolxml')
|
|
rpm-build |
d9acb6 |
# run without lxml
|
|
rpm-build |
d9acb6 |
import_lxml = False
|
|
rpm-build |
d9acb6 |
except ValueError:
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
sys.argv.remove('-z')
|
|
rpm-build |
d9acb6 |
# reset callgrind after tree setup
|
|
rpm-build |
d9acb6 |
callgrind_zero = True
|
|
rpm-build |
d9acb6 |
except ValueError:
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
initArgs(sys.argv)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
_etrees = []
|
|
rpm-build |
d9acb6 |
if import_lxml:
|
|
rpm-build |
d9acb6 |
from lxml import etree
|
|
rpm-build |
d9acb6 |
_etrees.append(etree)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
sys.argv.remove('-fel')
|
|
rpm-build |
d9acb6 |
except ValueError:
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
# use fast element creation in lxml.etree
|
|
rpm-build |
d9acb6 |
etree.set_element_class_lookup(
|
|
rpm-build |
d9acb6 |
etree.ElementDefaultClassLookup())
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
if len(sys.argv) > 1:
|
|
rpm-build |
d9acb6 |
if '-a' in sys.argv or '-c' in sys.argv:
|
|
rpm-build |
d9acb6 |
# 'all' or 'C-implementations' ?
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
sys.argv.remove('-c')
|
|
rpm-build |
d9acb6 |
except ValueError:
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
import cElementTree as cET
|
|
rpm-build |
d9acb6 |
_etrees.append(cET)
|
|
rpm-build |
d9acb6 |
except ImportError:
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
import xml.etree.cElementTree as cET
|
|
rpm-build |
d9acb6 |
_etrees.append(cET)
|
|
rpm-build |
d9acb6 |
except ImportError:
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
# 'all' ?
|
|
rpm-build |
d9acb6 |
sys.argv.remove('-a')
|
|
rpm-build |
d9acb6 |
except ValueError:
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
from elementtree import ElementTree as ET
|
|
rpm-build |
d9acb6 |
_etrees.append(ET)
|
|
rpm-build |
d9acb6 |
except ImportError:
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
from xml.etree import ElementTree as ET
|
|
rpm-build |
d9acb6 |
_etrees.append(ET)
|
|
rpm-build |
d9acb6 |
except ImportError:
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
if not _etrees:
|
|
rpm-build |
d9acb6 |
print("No library to test. Exiting.")
|
|
rpm-build |
d9acb6 |
sys.exit(1)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
print("Preparing test suites and trees ...")
|
|
rpm-build |
d9acb6 |
selected = set( sys.argv[1:] )
|
|
rpm-build |
d9acb6 |
benchmark_suites, benchmarks = \
|
|
rpm-build |
d9acb6 |
buildSuites(benchmark_class, _etrees, selected)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
print("Running benchmark on", ', '.join(b.lib_name
|
|
rpm-build |
d9acb6 |
for b in benchmark_suites))
|
|
rpm-build |
d9acb6 |
print('')
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
printSetupTimes(benchmark_suites)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
if callgrind_zero:
|
|
rpm-build |
d9acb6 |
cmd = open("callgrind.cmd", 'w')
|
|
rpm-build |
d9acb6 |
cmd.write('+Instrumentation\n')
|
|
rpm-build |
d9acb6 |
cmd.write('Zero\n')
|
|
rpm-build |
d9acb6 |
cmd.close()
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
runBenchmarks(benchmark_suites, benchmarks)
|