Skip to content

Commit

Permalink
perf: let EventedSet use clear() method of underlying set (#307)
Browse files Browse the repository at this point in the history
* perf: use clear method of underlying set

* add benchmark

* fix benchmark
  • Loading branch information
DanGonite57 authored May 6, 2024
1 parent b0c2952 commit 4c73b4d
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
3 changes: 3 additions & 0 deletions benchmarks/benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ def time_update_existing(self, n):
def time_update_overlap(self, n):
self.my_set.update(range(n // 2, n + n // 2))

def time_clear(self, _):
self.my_set.clear()


class EventedSetWithCallbackSuite(EventedSetSuite):
def setup(self, n):
Expand Down
20 changes: 20 additions & 0 deletions src/psygnal/containers/_evented_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ def discard(self, item: _T) -> None:
self._do_discard(_item)
self._post_discard_hook(_item)

def clear(self) -> None:
_item = self._pre_clear_hook()
if not isinstance(_item, BailType):
self._do_clear()
self._post_clear_hook(_item)

def __contains__(self, value: object) -> bool:
"""Return True if value is in set."""
return value in self._data
Expand Down Expand Up @@ -91,12 +97,20 @@ def _pre_discard_hook(self, item: _T) -> _T | BailType:

def _post_discard_hook(self, item: _T) -> None: ...

def _pre_clear_hook(self) -> tuple[_T, ...] | BailType:
return tuple(self) # pragma: no cover

def _post_clear_hook(self, item: tuple[_T, ...]) -> None: ...

def _do_add(self, item: _T) -> None:
self._data.add(item)

def _do_discard(self, item: _T) -> None:
self._data.discard(item)

def _do_clear(self) -> None:
self._data.clear()

# -------- To match set API

def __copy__(self) -> Self:
Expand Down Expand Up @@ -300,6 +314,12 @@ def _pre_discard_hook(self, item: _T) -> _T | BailType:
def _post_discard_hook(self, item: _T) -> None:
self._emit_change((), (item,))

def _pre_clear_hook(self) -> tuple[_T, ...] | BailType:
return BAIL if len(self) == 0 else tuple(self)

def _post_clear_hook(self, item: tuple[_T, ...]) -> None:
self._emit_change((), item)

def _emit_change(self, added: tuple[_T, ...], removed: tuple[_T, ...]) -> None:
"""Emit a change event."""
self.events.items_changed.emit(added, removed)
Expand Down

0 comments on commit 4c73b4d

Please sign in to comment.