I have several instance methods that use self
within them, but only in a couple places.
I can pass the objects to these methods directly and make them staticmethod
s. Does that consume less memory?
You are micro-optimising here for no benefit.
Yes, a regular method involves a new method
object that is created to handle the binding between function and instance, but that's only a bit of memory (2 pointers plus some Python metadata) used only during the duration of the call or if you stored the bound method *. A staticmethod
object doesn't create a new method object, but that's offset by the about the same amount of memory needed for the staticmethod
object:
>>> import sys
>>> class Foo:
... def bar(self): pass
... @staticmethod
... def staticbar(): pass
...
>>> sys.getsizeof(Foo().bar) # bound method object size
64
>>> sys.getsizeof(Foo.__dict__['staticbar']) # staticmethod size
56
So using a staticmethod
object saves you 8 bytes (on Mac OS X, on another OS the byte count could differ slightly), but you don't usually keep a bound method (you'd use instance.method()
, which creates the method object then discards it again after calling).
So, unless you are storing a large number of bound methods, this is not going to make enough difference to justify making your code unreadable by passing in the instance manually everywhere.
* Note that as of Python 3.7, for common cases Python doesn't even create method objects anymore. See the Optimisations section of the 3.7 What's New notes:
Method calls are now up to 20% faster due to the bytecode changes which avoid creating bound method instances.
This applies to <expr>.attribute_name(...)
call sequences, so an attribute name lookup followed directly by a call, in the same overall expression, provided only positional arguments are used. Special bytecodes are generated that validate that attribute_name
resolves to a method name on the class, then calls the underlying function directly with the result of <expr>
prepended. Python uses LOAD_METHOD
followed by CALL_METHOD
opcodes instead of LOAD_ATTR
and CALL_FUNCTION
opcodes, but falls back to the behaviour of the latter two if the optimisation doesn't apply.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With