Skip to content

Commit

Permalink
Domain __eq__: only cache 10 domains
Browse files Browse the repository at this point in the history
  • Loading branch information
markotoplak committed Jul 26, 2024
1 parent f37cd59 commit 975fa5e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
11 changes: 10 additions & 1 deletion Orange/data/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def __init__(self, attributes, class_vars=None, metas=None, source=None):
self.anonymous = False

self._hash = None # cache for __hash__()
self._eq_cache = IDWeakrefCache({}) # cache for __eq__()
self._eq_cache = IDWeakrefCache(_LRS10Dict()) # cache for __eq__()

def _ensure_indices(self):
if self._indices is None:
Expand Down Expand Up @@ -536,3 +536,12 @@ def __hash__(self):
if self._hash is None:
self._hash = hash(self.attributes) ^ hash(self.class_vars) ^ hash(self.metas)
return self._hash


class _LRS10Dict(dict):
""" A small "least recently stored" (not LRU) dict """

def __setitem__(self, key, value):
if len(self) >= 10:
del self[next(iter(self))]
super().__setitem__(key, value)
19 changes: 19 additions & 0 deletions Orange/tests/test_domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,25 @@ def __hash__(self):
domain1._eq_cache[(domain2,)] = False # pylint: disable=protected-access
self.assertFalse(domain1 == domain2)

def test_eq_cache_not_grow(self):
var = ContinuousVariable('var')
domain = Domain([var])
domains = [Domain([var]) for _ in range(10)]
for d in domains:
self.assertTrue(domain == d)

# __eq__ results to all ten domains should be cached
for d in domains:
domain._eq_cache[(d,)] # pylint: disable=protected-access

dn = Domain([var])
self.assertTrue(domain == dn)
# the last compared domain should be cached
domain._eq_cache[(dn,)] # pylint: disable=protected-access
# but the first compared should be lost in cache
with self.assertRaises(KeyError):
domain._eq_cache[(domains[0],)] # pylint: disable=protected-access

def test_domain_conversion_is_fast_enough(self):
attrs = [ContinuousVariable("f%i" % i) for i in range(10000)]
class_vars = [ContinuousVariable("c%i" % i) for i in range(10)]
Expand Down

0 comments on commit 975fa5e

Please sign in to comment.