From e979ed356b76e26571cffac827d0bd0dbb7c33f8 Mon Sep 17 00:00:00 2001 From: David Buxton Date: Wed, 8 Sep 2021 20:15:06 +0100 Subject: [PATCH] Speed up the PageIterator by evaluating items once per page The `firebase_admin.auth.list_users().iterate_all()` method uses a sub-class of PageIterator, which happens to access the .items computed property more than once for every page of results. This has been changed so we take care not to access the `self.items` property more than once per page. This is a lot faster. --- firebase_admin/_auth_utils.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/firebase_admin/_auth_utils.py b/firebase_admin/_auth_utils.py index e368342e8..02d32b659 100644 --- a/firebase_admin/_auth_utils.py +++ b/firebase_admin/_auth_utils.py @@ -43,30 +43,32 @@ class PageIterator: def __init__(self, current_page): if not current_page: raise ValueError('Current page must not be None.') + self._current_page = current_page - self._index = 0 + self._iter = None + + def __next__(self): + if self._iter is None: + self._iter = iter(self.items) - def next(self): - if self._index == len(self.items): + try: + return next(self._iter) + except StopIteration: if self._current_page.has_next_page: self._current_page = self._current_page.get_next_page() - self._index = 0 - if self._index < len(self.items): - result = self.items[self._index] - self._index += 1 - return result - raise StopIteration + self._iter = iter(self.items) - @property - def items(self): - raise NotImplementedError + return next(self._iter) - def __next__(self): - return self.next() + raise def __iter__(self): return self + @property + def items(self): + raise NotImplementedError + def get_emulator_host(): emulator_host = os.getenv(EMULATOR_HOST_ENV_VAR, '')