Skip to content

Commit 20991aa

Browse files
committed
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 change keeps most of the iterator state in the class init, meaning we can avoid accessing the computed property until the current page is exhausted. This is a lot faster.
1 parent 01db7eb commit 20991aa

File tree

1 file changed

+14
-15
lines changed

1 file changed

+14
-15
lines changed

firebase_admin/_auth_utils.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,30 +43,29 @@ class PageIterator:
4343
def __init__(self, current_page):
4444
if not current_page:
4545
raise ValueError('Current page must not be None.')
46+
4647
self._current_page = current_page
47-
self._index = 0
48+
self._iter = iter(self.items)
4849

49-
def next(self):
50-
if self._index == len(self.items):
50+
def __next__(self):
51+
try:
52+
return next(self._iter)
53+
except StopIteration:
5154
if self._current_page.has_next_page:
5255
self._current_page = self._current_page.get_next_page()
53-
self._index = 0
54-
if self._index < len(self.items):
55-
result = self.items[self._index]
56-
self._index += 1
57-
return result
58-
raise StopIteration
56+
self._iter = iter(self.items)
5957

60-
@property
61-
def items(self):
62-
raise NotImplementedError
63-
64-
def __next__(self):
65-
return self.next()
58+
return next(self._iter)
59+
else:
60+
raise
6661

6762
def __iter__(self):
6863
return self
6964

65+
@property
66+
def items(self):
67+
raise NotImplementedError
68+
7069

7170
def get_emulator_host():
7271
emulator_host = os.getenv(EMULATOR_HOST_ENV_VAR, '')

0 commit comments

Comments
 (0)