On Dec 2, 4:38 am, Anssi Kääriäinen <anssi.kaariai...@thl.fi> wrote: > - Have the "I'm mutable" flag for fields. I don't know if this is > workable from performance standpoint. In practice the implementation > could be descriptor based for in-place mutable fields.
I implemented POC of this and __setattr__ based way of traking variable changes. I think the solution given in the linked github branch could work. It is currently ugly, especially the save signature, which has new flags compat_mode and only_changed (came nearly free as side-product of this). The interaction between the different flags is the ugliest part. Now for the funny part of this. I suspected that __setattr__ would make init slower. But using a little trick, __init__ is now actually almost 30% faster for a 10 field model. The trick is checking if setattr needs to be called. It needs to be called if the user has defined __setattr__ for some subclass of Model, otherwise we can call directly object.__setattr__. For some reason, this is considerably faster than calling setattr(self, f.attname, val). I hope the approach is acceptable. The same trick could be employed directly to trunk version of Django, resulting in the same speedup. The biggest problems I see with the above mentioned hack are that 1) this is a hack, 2) this does not support dynamically changing __setattr__. I would not worry about 2), that seems fragile as hell anyways. This could be fixed if need be. 3) I do not know Python well enough to say if this hack will skip some crucial thing setattr would do. And 4) how does this interact with other versions of Python (pypy for example). On the other hand this is just the normal Python performance optimization: set commonly used attributes to local scope and use them from there to avoid lookup overhead. Without the hack, model __init__ will be up to 100% slower than currently, so that hack is a requirement for __setattr__ being acceptable. Apart of the above mentioned problems there are some TODOs: - I haven't tested MutableFieldDescriptor almost at all. - Currently save() after changing PK (to other value than None) will raise Exception, DeprecationWarning was the goal. - Rethink the logic in save_base. - Are there common situation where this leads to performance losses? setting object attributes will be considerably slower. - Get some feedback: is the approach taken is too crazy? - Verify that the approach really works... All tests do pass on sqlite3 (with 2 UnicodeWarnings). Code is here: https://github.com/akaariai/django/compare/master...save_change_pk2 Maybe I should open a ticket for this and move this discussion to trac? - Anssi -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.