Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does python static method consume less memory than instance method

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?

like image 336
Akshay Sharma Avatar asked Jul 04 '17 06:07

Akshay Sharma


Video Answer


1 Answers

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.

like image 89
Martijn Pieters Avatar answered Oct 21 '22 00:10

Martijn Pieters