diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-03-15 09:12:44 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-03-15 09:12:44 +0000 |
| commit | 7534ef1f7e86a301a2dd788855095262d2925832 (patch) | |
| tree | d125146bf084a5ad575118e067fe833f9946ad10 | |
| parent | d08ec8122899697fcbc7aa2868d9b1baadb24e2b (diff) | |
queryset-refactor: Optimised len(qs) and iter(qs) a bit.
git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7246 bcc190cf-cafb-0310-a4f2-bffc1f526a37
| -rw-r--r-- | django/db/models/query.py | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py index bd2cf8dbaa..e13aed393e 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -28,16 +28,32 @@ class _QuerySet(object): ######################## def __repr__(self): - return repr(list(iter(self))) + return repr(list(self)) def __len__(self): - return len(list(iter(self))) + # Since __len__ is called quite frequently (as part of list(qs), which + # means as part of qs.get(), for example), we make some effort here to + # be as efficient as possible whilst not messing up any existing + # iterators against the queryset. + if self._result_cache is None: + if self._iter: + self._result_cache = list(self._iter()) + else: + self._result_cache = list(self.iterator()) + elif self._iter: + self.result_cache.extend(list(self._iter)) + return len(self._result_cache) def __iter__(self): - pos = 0 if self._result_cache is None: self._iter = self.iterator() self._result_cache = [] + if self._iter: + return self._result_iter() + return iter(self._result_cache) + + def _result_iter(self): + pos = 0 while 1: upper = len(self._result_cache) while pos < upper: |
