#27624: Optimize ORM by using more immutable data structures
-------------------------------------+-------------------------------------
Reporter: Adam Chainz | Owner: Adam
Type: | Chainz
Cleanup/optimization | Status: assigned
Component: Database layer | Version: 1.10
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Adam Chainz):
Note: if all of `Query`'s attributes were immutable, we could probably
greatly speed up its instantiation and copying by not having every
attribute defined on every instance, and relying on fallback to class
level defaults, then `clone()` doing a simple
`new.__dict__.update(self.__dict__)` to copy all the non-default
attributes. For example, take these two classes:
{{{
In [24]: class Foo(object):
...: def __init__(self):
...: self.x = None
...: self.y = None
...: self.z = None
...: def clone(self):
...: obj = self.__class__()
...: obj.x = self.x
...: obj.y = self.y
...: obj.z = self.z
...: return obj
...:
In [25]: class Foo2(object):
...: x = None
...: y = None
...: z = None
...: def __init__(self):
...: pass
...: def clone(self):
...: obj = self.__class__()
...: obj.__dict__.update(self.__dict__)
...: return obj
...:
}}}
The first example corresponds to the current situation with `Query`, and
the bottom is the imagined future. Timing the example `__init__` +
`clone()` methods gives:
{{{
In [26]: %timeit -n 1000000 -r 3 Foo().clone()
1000000 loops, best of 3: 1.82 µs per loop
In [27]: %timeit -n 1000000 -r 3 Foo2().clone()
1000000 loops, best of 3: 1.3 µs per loop
}}}
This is about a 30% speed up. Inspecting just the `clone()` methods
because we care a bit more about the time that takes over `__init__`,
gives us:
{{{
In [31]: foo = Foo()
In [32]: %timeit -n 1000000 -r 3 foo.clone()
1000000 loops, best of 3: 1.15 µs per loop
In [33]: foo2 = Foo2()
In [34]: %timeit -n 1000000 -r 3 foo2.clone()
1000000 loops, best of 3: 874 ns per loop
}}}
About a 25% speed boost, very similar.
The difference will hopefully be even greater on `Query` as currently its
`clone()` method is 69 lines long with many attributes getting copied.
--
Ticket URL: <https://code.djangoproject.com/ticket/27624#comment:5>
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/068.788a1b7f58c934bb9a74373af307d402%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.