From 7534ef1f7e86a301a2dd788855095262d2925832 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Sat, 15 Mar 2008 09:12:44 +0000 Subject: [PATCH] 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 --- django/db/models/query.py | 22 +++++++++++++++++++--- 1 file 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: