Commit b9cd866a authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

* optimise sortValueList().

  * use sort(key=func) instead of sort(cmp=func) if possible.
  * cache keyword arguments for sort().


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@23875 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 146e7c6c
...@@ -65,24 +65,35 @@ from Accessor.TypeDefinition import list_types ...@@ -65,24 +65,35 @@ from Accessor.TypeDefinition import list_types
# Generic sort method # Generic sort method
##################################################### #####################################################
sort_kw_cache = {}
def sortValueList(value_list, sort_on=None, sort_order=None, **kw): def sortValueList(value_list, sort_on=None, sort_order=None, **kw):
"""Sort values in a way compatible with ZSQLCatalog. """Sort values in a way compatible with ZSQLCatalog.
""" """
if sort_on is not None: if sort_on is not None:
if isinstance(sort_on, str): if isinstance(sort_on, str):
sort_on = (sort_on,) sort_on = (sort_on,)
reverse = (sort_order in ('descending', 'reverse', 'DESC')) # try to cache keyword arguments for sort()
sort_on = tuple([isinstance(x, str) and x or tuple(x) for x in sort_on])
try:
sort_kw = sort_kw_cache[sort_on]
except KeyError:
new_sort_on = [] new_sort_on = []
reverse_dict = {}
for key in sort_on: for key in sort_on:
if isinstance(key, str): if isinstance(key, str):
reverse = (sort_order in ('descending', 'reverse', 'DESC'))
new_sort_on.append((key, reverse, None)) new_sort_on.append((key, reverse, None))
reverse_dict[reverse] = True
else: else:
if len(key) == 1: if len(key) == 1:
reverse = (sort_order in ('descending', 'reverse', 'DESC'))
new_sort_on.append((key[0], reverse, None)) new_sort_on.append((key[0], reverse, None))
reverse_dict[reverse] = True
elif len(key) == 2: elif len(key) == 2:
new_sort_on.append((key[0], reverse = (key[1] in ('descending', 'reverse', 'DESC'))
key[1] in ('descending', 'reverse', 'DESC'), new_sort_on.append((key[0], reverse, None))
None)) reverse_dict[reverse] = True
else: else:
# Emulate MySQL types # Emulate MySQL types
as_type = key[2].lower() as_type = key[2].lower()
...@@ -93,14 +104,32 @@ def sortValueList(value_list, sort_on=None, sort_order=None, **kw): ...@@ -93,14 +104,32 @@ def sortValueList(value_list, sort_on=None, sort_order=None, **kw):
else: else:
# XXX: For an unknown type, use a string. # XXX: For an unknown type, use a string.
f=str f=str
new_sort_on.append((key[0], reverse = (key[1] in ('descending', 'reverse', 'DESC'))
key[1] in ('descending', 'reverse', 'DESC'), new_sort_on.append((key[0], reverse, f))
f)) reverse_dict[reverse] = True
sort_on = new_sort_on
if len(reverse_dict) == 1:
# if we have only one kind of reverse value (i.e. all True or all
# False), we can use sort(key=func) that is faster than
# sort(cmp=func).
def sortValue(a):
value_list = []
for key, reverse, as_type in new_sort_on:
x = a.getProperty(key, None)
if as_type is not None:
try:
x = as_type(x)
except TypeError:
pass
value_list.append(x)
return value_list
sort_kw = {'key':sortValue, 'reverse':reverse}
sort_kw_cache[sort_on] = sort_kw
else:
# otherwise we use sort(cmp=func).
def sortValues(a, b): def sortValues(a, b):
result = 0 result = 0
for key, reverse, as_type in sort_on: for key, reverse, as_type in new_sort_on:
x = a.getProperty(key, None) x = a.getProperty(key, None)
y = b.getProperty(key, None) y = b.getProperty(key, None)
if as_type is not None: if as_type is not None:
...@@ -115,11 +144,14 @@ def sortValueList(value_list, sort_on=None, sort_order=None, **kw): ...@@ -115,11 +144,14 @@ def sortValueList(value_list, sort_on=None, sort_order=None, **kw):
if result != 0: if result != 0:
break break
return result return result
sort_kw = {'cmp':sortValues, 'reverse':reverse}
sort_kw_cache[sort_on] = sort_kw
if isinstance(value_list, LazyMap): if isinstance(value_list, LazyMap):
new_value_list = [x for x in value_list] new_value_list = [x for x in value_list]
value_list = new_value_list value_list = new_value_list
value_list.sort(sortValues)
value_list.sort(**sort_kw)
return value_list return value_list
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment