Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.2.X] Fixed #14697 - speeded up model instance creation by moving w…

…ork outside of loops

Thanks to akaariai for the report and initial patch.

Backport of [14687] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@14688 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 1c451c0f395a14e426c17a8eb059669fa3d0d7ab 1 parent c2de746
Luke Plant authored
23  django/db/models/query.py
@@ -264,11 +264,14 @@ def iterator(self):
264 264
                     init_list.append(field.attname)
265 265
             model_cls = deferred_class_factory(self.model, skip)
266 266
 
267  
-        compiler = self.query.get_compiler(using=self.db)
  267
+        # Cache db and model outside the loop
  268
+        db = self.db
  269
+        model = self.model
  270
+        compiler = self.query.get_compiler(using=db)
268 271
         for row in compiler.results_iter():
269 272
             if fill_cache:
270  
-                obj, _ = get_cached_row(self.model, row,
271  
-                            index_start, using=self.db, max_depth=max_depth,
  273
+                obj, _ = get_cached_row(model, row,
  274
+                            index_start, using=db, max_depth=max_depth,
272 275
                             requested=requested, offset=len(aggregate_select),
273 276
                             only_load=only_load)
274 277
             else:
@@ -278,19 +281,21 @@ def iterator(self):
278 281
                     obj = model_cls(**dict(zip(init_list, row_data)))
279 282
                 else:
280 283
                     # Omit aggregates in object creation.
281  
-                    obj = self.model(*row[index_start:aggregate_start])
  284
+                    obj = model(*row[index_start:aggregate_start])
282 285
 
283 286
                 # Store the source database of the object
284  
-                obj._state.db = self.db
  287
+                obj._state.db = db
285 288
                 # This object came from the database; it's not being added.
286 289
                 obj._state.adding = False
287 290
 
288  
-            for i, k in enumerate(extra_select):
289  
-                setattr(obj, k, row[i])
  291
+            if extra_select:
  292
+                for i, k in enumerate(extra_select):
  293
+                    setattr(obj, k, row[i])
290 294
 
291 295
             # Add the aggregates to the model
292  
-            for i, aggregate in enumerate(aggregate_select):
293  
-                setattr(obj, aggregate, row[i+aggregate_start])
  296
+            if aggregate_select:
  297
+                for i, aggregate in enumerate(aggregate_select):
  298
+                    setattr(obj, aggregate, row[i+aggregate_start])
294 299
 
295 300
             yield obj
296 301
 
3  django/db/models/sql/compiler.py
@@ -669,6 +669,7 @@ def results_iter(self):
669 669
         """
670 670
         resolve_columns = hasattr(self, 'resolve_columns')
671 671
         fields = None
  672
+        has_aggregate_select = bool(self.query.aggregate_select)
672 673
         for rows in self.execute_sql(MULTI):
673 674
             for row in rows:
674 675
                 if resolve_columns:
@@ -689,7 +690,7 @@ def results_iter(self):
689 690
                                       f.column in only_load[db_table]]
690 691
                     row = self.resolve_columns(row, fields)
691 692
 
692  
-                if self.query.aggregate_select:
  693
+                if has_aggregate_select:
693 694
                     aggregate_start = len(self.query.extra_select.keys()) + len(self.query.select)
694 695
                     aggregate_end = aggregate_start + len(self.query.aggregate_select)
695 696
                     row = tuple(row[:aggregate_start]) + tuple([

0 notes on commit 1c451c0

Please sign in to comment.
Something went wrong with that request. Please try again.