#19501: Allow for fast path model loading -------------------------------------+------------------------------------- Reporter: akaariai | Owner: akaariai Type: | Status: new Cleanup/optimization | Version: master Component: Database layer | Resolution: (models, ORM) | Triage Stage: Accepted Severity: Normal | Needs documentation: 0 Keywords: | Patch needs improvement: 0 Has patch: 1 | UI/UX: 0 Needs tests: 0 | Easy pickings: 0 | -------------------------------------+------------------------------------- Changes (by akaariai):
* needs_better_patch: 1 => 0 Comment: I updated the code and docs based on review comments. The code was mistakenly creating a new model._state in from_db() method, when just updating the attributes of the existing ._state instance is enough. Now the slowdown (using djangobench) is: {{{ Running 'query_select_related' benchmark ... Min: 0.054252 -> 0.058567: 1.0795x slower Avg: 0.055689 -> 0.059967: 1.0768x slower Significant (t=-8.076647) Stddev: 0.00271 -> 0.00258: 1.0494x smaller (N = 50) Running 'query_all' benchmark ... Min: 0.021309 -> 0.022659: 1.0633x slower Avg: 0.022763 -> 0.024240: 1.0649x slower Significant (t=-2.598991) Stddev: 0.00285 -> 0.00283: 1.0042x smaller (N = 50) Running 'query_raw_deferred' benchmark ... Min: 0.016543 -> 0.017822: 1.0773x slower Avg: 0.017149 -> 0.018389: 1.0723x slower Significant (t=-4.172737) Stddev: 0.00150 -> 0.00147: 1.0174x smaller (N = 50) }}} So, the code itself causes a minor slowdown. The benchmarks done in above comments and the ticket's description test various fast-path implementations. Basically, one can do the following for their model: {{{ class Empty(object): pass class MyModel(models.Model): ... @classmethod def from_db(cls, db, field_names, values): empty = Empty() empty.__class__ = cls empty.__dict__ = zip(field_names, values) empty._state = ModelState() empty._state.adding = False return empty }}} and this results in around 2x better performance for query_all benchmark, and 4x speedup for deferred model loading (query_defer benchmark). This ticket discussed various ways to do automatically the above optimization - it is possible to do if the model doesn't have customized ``__init__``, doesn't have pre/post init signals, and calling setattr isn't required for the model. Detecting this seems too complex, so the automation isn't there any more. However, users who require absolute performance can do the optimization manually if needed. -- Ticket URL: <https://code.djangoproject.com/ticket/19501#comment:9> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/066.b212805aa835e1a388cb0605b21b3cc3%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.