[IMP] api, models: _write performances on import
Followup from the previous commit: before this, _write takes 32% of total runtime, of which 13.7% is ultimately assignable to add_todo. Turns out for the test case we mostly keep adding records to recorsets where they're already present, so the 13.7% of runtime in add_todo are mostly spent creating orderedsets (11.17) then converting those back into recordsets (1.75%) with some time spent creating lists and appending records (already present) in them. Checking if the records are already present before merging them in decreases add_todo's runtime cost to 0.5%, and ultimately _write to 20%. As many of the ignorable calls were merging a singleton or an empty recorset into the parent recordset, optimising for these cases was added to BaseModel's <= and >=.
This commit is contained in:
+5
-1
@@ -955,7 +955,11 @@ class Environment(Mapping):
|
||||
recs_list = self.all.todo.setdefault(field, [])
|
||||
for i, recs in enumerate(recs_list):
|
||||
if recs.env == records.env:
|
||||
recs_list[i] |= records
|
||||
# only add records if not already in the recordset, much much
|
||||
# cheaper in case recs is big and records is a singleton
|
||||
# already present
|
||||
if not records <= recs:
|
||||
recs_list[i] |= records
|
||||
break
|
||||
else:
|
||||
recs_list.append(records)
|
||||
|
||||
@@ -4963,6 +4963,11 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
||||
def __le__(self, other):
|
||||
if not isinstance(other, BaseModel) or self._name != other._name:
|
||||
raise TypeError("Mixing apples and oranges: %s <= %s" % (self, other))
|
||||
# these are much cheaper checks than a proper subset check, so
|
||||
# optimise for checking if a null or singleton are subsets of a
|
||||
# recordset
|
||||
if not self or self in other:
|
||||
return True
|
||||
return set(self._ids) <= set(other._ids)
|
||||
|
||||
def __gt__(self, other):
|
||||
@@ -4973,6 +4978,8 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
||||
def __ge__(self, other):
|
||||
if not isinstance(other, BaseModel) or self._name != other._name:
|
||||
raise TypeError("Mixing apples and oranges: %s >= %s" % (self, other))
|
||||
if not other or other in self:
|
||||
return True
|
||||
return set(self._ids) >= set(other._ids)
|
||||
|
||||
def __int__(self):
|
||||
|
||||
Reference in New Issue
Block a user