#24591: Copy ModelState.fields and ModelState.managers instead of clone
--------------------------------------+--------------------
     Reporter:  knbk                  |      Owner:  knbk
         Type:  Cleanup/optimization  |     Status:  new
    Component:  Migrations            |    Version:  master
     Severity:  Normal                |   Keywords:
 Triage Stage:  Unreviewed            |  Has patch:  1
Easy pickings:  0                     |      UI/UX:  0
--------------------------------------+--------------------
 Fields in a`ModelState` are guaranteed to not be bound to a model, and are
 deconstructed and reconstructed in `ModelState.from_model()`. They are
 also properly deconstructed and reconstructed when rendering a model.
 Furthermore, the fields themselves must not change during the lifetime of
 a `ModelState` object, though you may freely add, remove and replace
 fields (1). They should be considered immutable within model states.

 I think the current implementation of `ModelState.clone()` is too
 conservative in this regard. Both the input (in `ModelState.from_model()`)
 and the output (in `ModelState.render()`) do a full de- and reconstruct.
 The only change in between is the addition and removal of fields from the
 list. `ModelState.clone()` can do a simple `list(self.fields)` and still
 maintain the correct behaviour. The same holds for `ModelState.managers`.
 This change saves about 75% in rendering time, and 66% in memory usage in
 my benchmarks.

 If you want to safeguard against accidental changes that can affect other
 model states, you can use `copy.deepcopy()`, though at a performance cost.
 Other options are to somehow shield against accidental changes by
 generating an immutable field class, or by saving the deconstructed field
 and constructing the fields on demand.

 As this is ''the'' most performance-critical part of migrations -- save
 the actual database manipulation -- I suggest we take a careful look into
 this. The current implementation with `deconstruct()` is far from the
 ideal solution.

 (1)
 https://github.com/django/django/blob/master/django/db/migrations/state.py#L294

--
Ticket URL: <https://code.djangoproject.com/ticket/24591>
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/047.1c5d38cdb0cc30e59016bb2a8a8a030a%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to