Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #14697 - speeded up model instance creation by moving work outs…

…ide of loops

Thanks to akaariai for the report and initial patch.

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

0 notes on commit ff7c243

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