【问题标题】:Does python static method consume less memory than instance methodpython静态方法是否比实例方法消耗更少的内存
【发布时间】:2017-12-07 12:17:18
【问题描述】:

我有几个在其中使用self 的实例方法,但只在几个地方。

我可以直接将对象传递给这些方法,并将它们设为staticmethods。这会消耗更少的内存吗?

【问题讨论】:

    标签: python python-3.x memory memory-management static-methods


    【解决方案1】:

    您在这里进行微优化,没有任何好处。

    是的,常规方法涉及一个新的 method 对象,该对象被创建用于处理函数和实例之间的绑定,但这只是一点内存(2 个指针加上一些 Python 元数据)仅在持续时间内使用调用或存储绑定方法 *staticmethod 对象不会创建新的方法对象,但这会被staticmethod 对象所需的内存量抵消

    >>> 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
    

    所以使用staticmethod 对象可以节省 8 个字节(在 Mac OS X 上,在另一个操作系统上字节数可能略有不同),但您通常不会保留绑定方法(您'd 使用instance.method(),它创建方法对象,然后在调用后再次丢弃它)。

    因此,除非您存储大量绑定方法,否则这并不足以证明通过在任何地方手动传递实例来使您的代码不可读。


    * 请注意,从 Python 3.7 开始,对于常见情况,Python 甚至不再创建方法对象。见Optimisations section of the 3.7 What's New notes

    由于避免创建绑定方法实例的字节码更改,方法调用现在提高了 20%。

    这适用于<expr>.attribute_name(...) 调用序列,因此在相同的整体表达式中,属性名称查找直接后跟调用,前提是仅使用位置参数。生成特殊字节码,验证attribute_name 解析为类上的方法名称,然后直接调用底层函数,并在前面加上<expr> 的结果。 Python 使用LOAD_METHOD 后跟CALL_METHOD 操作码而不是LOAD_ATTRCALL_FUNCTION 操作码,但如果优化不适用,则回退到后两者的行为。

    【讨论】:

    • 但就我的尝试而言,为每个实例创建了绑定方法,不是每个实例都有额外的内存吗?
    • @EkremDİNÇEL:在我的回答中指出:仅在通话期间使用或存储绑定方法时使用。如果您没有为每个实例存储绑定方法,则没有使用内存,方法对象通常仅短暂存在。在现代 Python 版本中,对于常见情况,Python 甚至不创建对象
    猜你喜欢
    • 1970-01-01
    • 2015-11-14
    • 1970-01-01
    • 2010-10-26
    • 2011-01-18
    • 2017-03-17
    • 2018-03-07
    • 2022-12-12
    • 2012-11-12
    相关资源
    最近更新 更多