Skip to content

Commit 591f299

Browse files
committed
Cache __eq__ in Domain
1 parent cd45d48 commit 591f299

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

Orange/data/domain.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import itertools
22
import warnings
3+
import weakref
34

45
from math import log
56
from collections.abc import Iterable
@@ -169,6 +170,7 @@ def __init__(self, attributes, class_vars=None, metas=None, source=None):
169170
self.anonymous = False
170171

171172
self._hash = None # cache for __hash__()
173+
self._eq_wdict = {} # cache for __eq__()
172174

173175
def _ensure_indices(self):
174176
if self._indices is None:
@@ -185,6 +187,7 @@ def __setstate__(self, state):
185187
self._variables = self.attributes + self.class_vars
186188
self._indices = None
187189
self._hash = None
190+
self._eq_wdict = {}
188191

189192
def __getstate__(self):
190193
# Do not pickle dictionaries because unpickling dictionaries that
@@ -195,6 +198,7 @@ def __getstate__(self):
195198
del state["_variables"]
196199
del state["_indices"]
197200
del state["_hash"]
201+
del state["_eq_wdict"]
198202
return state
199203

200204
# noinspection PyPep8Naming
@@ -518,11 +522,30 @@ def __eq__(self, other):
518522
if not isinstance(other, Domain):
519523
return False
520524

521-
return (self.attributes == other.attributes and
522-
self.class_vars == other.class_vars and
523-
self.metas == other.metas)
525+
# cache by ID because
526+
eq = _idcache_restore(self._eq_wdict, (other,))
527+
if eq is None:
528+
eq = (self.attributes == other.attributes and
529+
self.class_vars == other.class_vars and
530+
self.metas == other.metas)
531+
_idcache_save(self._eq_wdict, (other,), eq)
532+
533+
return eq
524534

525535
def __hash__(self):
526536
if self._hash is None:
527537
self._hash = hash(self.attributes) ^ hash(self.class_vars) ^ hash(self.metas)
528538
return self._hash
539+
540+
541+
def _idcache_save(cachedict, keys, value):
542+
cachedict[tuple(map(id, keys))] = \
543+
value, [weakref.ref(k) for k in keys]
544+
545+
546+
def _idcache_restore(cachedict, keys):
547+
shared, weakrefs = cachedict.get(tuple(map(id, keys)), (None, []))
548+
for r in weakrefs:
549+
if r() is None:
550+
return None
551+
return shared

0 commit comments

Comments
 (0)