10

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 staticmethods. Does that consume less memory?

1 Answer 1

20

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.

Sign up to request clarification or add additional context in comments.

2 Comments

But as far as I tried, bound methods were created for each instance, isn't that extra memory for each instance?
@EkremDİNÇEL: I address that in my answer: used only during the duration of the call or if you stored the bound method. If you are not storing bound methods for every instance, there is no memory used, method objects generally exist only briefly. In modern Python releases, for the common cases, Python doesn't even create the object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.