Saving 9 GB of RAM with Python's __slots__
tech.oyster.com
tech.oyster.com
PyPy might be an interesting project with much potential, but there seams to me a long way until it can be an one-shot replacement for CPyton.
No, this is a cost of this particular style of dynamic object model. Not all dynamic languages are dynamic in this way.
> Those objects are not enhance-able any more.
I don't see any reason why Python can't do what Clojure's defrecord does: Provide fixed fields for pre-declared slots, while still using a dictionary for extensions. It has been a while since I've used python, but I'm almost certain that there is some __special__ magic that can make this work with relative ease.
It's also worth pointing out that most modern JITs, like V8 or PyPy, can automatically detect "hidden classes" like this and optimize these objects to pack such static fields.
Pythons style has some advantages though. Simplicity and really a huge quantity of flexibility are two of them.
(Traditional) Python normally is not a truly compiled language -- it is just a rather simple precompilation step that makes life easier for the interpreter. When you compile or "JIT" the code, you have more options. You see the whole program. The precompiler of Python does not! It just sees the local module. So, it can not find all classes that might enhance a base class.
If you have any ideas, how to implement a better language, why don't you implement your own? It's up to you! (I guess, creating new (more or less useful) programming languages is the hobby of computer scientists anyhow)
While language semantics do influence the quality of what is possible implementation wise, they are not the same thing.
This is usually true when, say, analyzing some data. If your design pattern is good, those object would be immutable anyway.
I posted this as a comment to the article:
-- I'm working on a Ruby compiler and have taken pretty much [the PyPy] approach [of automatically using slots when possible]: Any instance variable names I can statically determine are candidates for the equivalent treatment (allocating a slot at a fixed offset in the object structure).
Anything else will still go in a dictionary. In practice my experience is that a huge proportion of objects will have a fairly static set of attributes, and the dynamic set is often small enough that having pointers them included in every instance is still often cheaper than using dictionaries. ---
In a static language, your options are generally to either statically allocate slots, or explicitly use a dictionary anyway.
Anyways, definitely a good short read, thanks for posting!
Test code at: http://codepad.org/wlb53BLf not sure if I'm missing something...
Most of the space for the NonSlotted version is in the __dict__, and if you print the size of ni.__dict__ you'll probably get a couple of hundred bytes.
There are better, recursive ways to get the real size of a Python object in memory, for example see: http://pythonhosted.org/Pympler/asizeof.html#asizeof
Try comment and un-comment the __slot__. You can measure the program memory footprint using
pmap -x <PID>
where <PID> is obtained using
pgrep python
...more than one python process?
cat /proc/<PID>/cmdline | xargs -0 echo
Although, there may be performance differences between `namedtuple` and `__slots__`. Particularly access time. This SO post elaborates.[1]
[1] - http://stackoverflow.com/questions/2646157/what-is-the-faste...
EDIT: Is it the new modus operandi on HN: If a statement isn't seemingly 100% in support of your pet language, automatically read the statement in the dimmest and narrowest way possible?
See also my comment on reddit about design decisions: http://www.reddit.com/r/programming/comments/1qu5ai/saving_9...
Does that fuck up? Rinse and repeat.
I echo what they said in that post, though: don't prematurely optimize. If you find you have tons of objects and need the RAM or you're actually paying a premium for hash accesses, then fields can save you some effort... but if you've a small use case, don't bother.
Works perfectly well, and empowers one to escape from it at a later date if necessary.
I am one of those.