PEP 412 是否会使 __slots__ 变得多余?

2024-03-30

PEP 412 http://www.python.org/dev/peps/pep-0412/在 Python 3.3 中实现,引入了对属性字典的改进处理,有效减少了类实例的内存占用。__slots__ http://docs.python.org/3/reference/datamodel.html?highlight=__slots__#object.__slots__是为了相同的目的而设计的,所以使用有什么意义吗__slots__还有吗?

为了自己找出答案,我运行了以下测试,但结果没有多大意义:

class Slots(object):
    __slots__ = ['a', 'b', 'c', 'd', 'e']
    def __init__(self):
        self.a = 1
        self.b = 1
        self.c = 1
        self.d = 1
        self.e = 1  

class NoSlots(object):
    def __init__(self):
        self.a = 1
        self.b = 1
        self.c = 1
        self.d = 1
        self.e = 1

Python 3.3 结果:

>>> sys.getsizeof([Slots() for i in range(1000)])
Out[1]: 9024
>>> sys.getsizeof([NoSlots() for i in range(1000)])
Out[1]: 9024

Python 2.7 结果:

>>> sys.getsizeof([Slots() for i in range(1000)])
Out[1]: 4516
>>> sys.getsizeof([NoSlots() for i in range(1000)])
Out[1]: 4516

我预计 Python 2.7 的大小至少会有所不同,所以我认为测试有问题。


不,PEP 412 可以not make __slots__多余的。


首先,阿明·里戈(Armin Rigo)是对的,你没有正确衡量它。您需要测量的是物体的大小,加上数值,加上__dict__本身(对于NoSlots仅)和钥匙(用于NoSlots only).

或者你可以按照他的建议去做:

cls = Slots if len(sys.argv) > 1 else NoSlots
def f():
    tracemalloc.start()
    objs = [cls() for _ in range(100000)]
    print(tracemalloc.get_traced_memory())
f()

当我在 OS X 上的 64 位 CPython 3.4 上运行它时,我得到8824968 for Slots and 25624872 for NoSlots。所以,它看起来像一个NoSlots实例占用 88 个字节,而一个Slots实例占用 256 字节。


这怎么可能?

因为仍然有两点不同__slots__和一个键分割__dict__.

首先,字典使用的哈希表保持在 2/3 以下,并且它们呈指数增长并具有最小大小,因此您将有一些额外的空间。通过查看好评的内容,不难算出有多少空间source http://hg.python.org/cpython/file/default/Objects/dictobject.c:您将拥有 8 个哈希桶,而不是 5 个槽指针。

其次,词典本身并不是免费的;它有一个标准对象头、一个计数和两个指针。这听起来可能不是很多,但是当你谈论一个只有几个属性的对象时(请注意most对象只有几个属性……),字典头可以像哈希表一样发挥作用。

当然,在您的示例中,是值,因此这里涉及的唯一成本是对象本身,加上 5 个插槽或 8 个哈希桶和 dict 标头,因此差异非常显着。在真实生活中,__slots__很少会that有很大的好处。


最后,请注意 PEP 412 仅声明:

基准测试表明,面向对象程序的内存使用量减少了 10% 到 20%

想想你在哪里使用__slots__。要么节省的金额太大,以至于不使用__slots__那就太荒谬了,否则你真的需要挤出最后 15%。或者您正在构建一个 ABC 或其他类,您希望将其子类化,而这些子类可能需要节省成本。无论如何,在这些情况下,事实上你获得了一半的好处,而无需__slots__,甚至三分之二的收益,仍然远远不够;你仍然需要使用__slots__.

真正的胜利是在不值得使用的情况下__slots__;您将免费获得一点小福利。

(另外,肯定有一些程序员过度使用了__slots__,也许这种改变可以说服他们中的一些人将精力投入到微观优化其他不太相关的事情上,如果你幸运的话。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PEP 412 是否会使 __slots__ 变得多余? 的相关文章

随机推荐

  • Spring Security 与 Struts 的集成

    我正在尝试在一个简单的应用程序中将 spring security 与 struts1 2 使用 LDAP 集成 我有 applicationContext security xml
  • ASP.NET MVC 5 和 Web API 2 .NET 要求

    我的主机提供商仅支持 NET 4 是否可以在 NET 4 计算机中运行 MVC 5 和 Web API 2 简短回答 不 您需要 NET 4 5 仅当添加依赖项时 剃须刀 v3 0 ASP NET 网页 v3 0
  • iPhone 在个人热点模式下不发送网络广播/组播

    根据最近的实证研究结果以及网络上的各种帖子 在启用了个人热点的 iPhone 上运行的应用程序似乎无法将广播和 或多播发送到个人热点的网络上 任何人都可以阐明这个问题的原因吗 应用程序 我有一个用跨平台 C 代码构建的 IOS 应用程序 它
  • 将图像添加到 Facebook 分享

    我正在尝试通过以下方式将图像添加到页面共享https developers facebook com docs plugins share button https developers facebook com docs plugins
  • 用于恢复保存后更改的宏

    我在网上找到了一个旧脚本来关闭文档而不保存更改 然后重新打开文档 Sub RevertFile wkname ActiveWorkbook Path ActiveWorkbook Name ActiveWorkbook Close Save
  • SQL Server while循环联合所有[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我正在尝试
  • SQL Server 日期时间过滤查询

    我在 SQL Server 中有这样的查询 SELECT Order Date SUM Profit FROM sample dbo superstore WHERE Order Date BETWEEN 2012 06 21 00 00
  • 获取Weblogic服务器上部署的所有应用程序的列表

    使用以下代码 我可以连接到 weblogic 服务器 现在我想获取服务器上部署的所有应用程序的列表 命令提示符下的 listapplications 列出了应用程序 但是当我执行terpreter exec listapplications
  • CXF 客户端安全

    我正在创建 Java Soap Web 服务的客户端 但无法弄清楚如何正确传递密码 这是我的 硬编码 密码示例 Test public void exploratorySecurityTest String username user St
  • WebClient Unicode - 哪种 UTF8?

    当我创建 WebClient 来使用一些 RESTful xml 时 我可以通过两种方式指定 unicode 编码 WebClient wc new WebClient wc Encoding Encoding UTF8 wc Encodi
  • 使用 CloudFront 部署在 S3 上的 VueJS 应用程序“指定的密钥不存在”

    我已经使用 Route53 部署了带有 S3 和 CloudFront 的 VueJS 应用程序 看起来一切都很顺利 我可以访问该网站https my domain com 我可以导航到我使用 Vue 路由器设置的不同路线 但是 当我尝试访
  • 在 Ionic 2 中使用图像资源的正确方法

    Ionic 2 中图像资源的最佳实践是什么 我有一堆 SVG 想用作非系统图标 我发现了一些关于使用 Gulp 的旧技巧 但似乎 Ionic 团队已决定将 Rollup 作为首选构建工具 到目前为止还没有相关文档 有人告诉我只需将它们添加到
  • 有没有办法通过 QueryDSL 中的 Predicate API 急切地获取惰性关系?

    我正在使用QueryDslPredicateExecutor来自 Spring Data JPA 项目 我面临着急于获取惰性关系的需要 我知道我可以在 Repository 接口中使用本机 JPA QL 查询 甚至可以使用 Query DS
  • 如何使用恢复按钮进入上一个活动?

    我的应用程序工作正常 但我的目的是当我关闭应用程序然后再次运行它时 我的应用程序将在最后一个活动中打开 我希望当我再次打开时 主要活动会显示出来 如果我单击 恢复 则最后一个活动将打开 所以我有4个Activity called Main
  • 内存警告后在 iOS 上运行 OpenGL 崩溃

    我遇到了带有 OpenGL 组件的应用程序在 iPad 上崩溃的问题 该应用程序抛出内存警告并崩溃 但它似乎没有使用那么多内存 我错过了什么吗 该应用程序基于 Vuforia 增强现实系统 大量借鉴了 ImageTargets 示例 我需要
  • 为什么将函数转换为除返回类型之外相同的函数类型会失败? [复制]

    这个问题在这里已经有答案了 可能的重复 返回类型是函数签名的一部分吗 https stackoverflow com questions 290038 is the return type part of the function sign
  • onSelectRow 中的 jqGrid 行对象

    如何获取 jqGrid 中选定行上的行对象 我需要实际的对象 而不是单元格值 我已阅读文档 但找不到可以为我提供行对象的方法 由于我使用自定义格式化程序 因此 cellValue 将不起作用 如果你实施自定义格式化程序 http www t
  • 阶乘递归

    我正在尝试编写一种算法来使用递归函数计算数字的阶乘 这是我的代码 include
  • 如果我们不注销 BroadcastReceiver 会发生什么?

    假设我动态注册一个广播接收器这是一个内部类Activity in onCreate 并且不要在代码中的任何地方取消注册它 现在假设finish 被调用 一段时间后 应用程序再次打开 会使用新的接收者对象吗 考虑到具有相同意图过滤器的旧接收器
  • PEP 412 是否会使 __slots__ 变得多余?

    PEP 412 http www python org dev peps pep 0412 在 Python 3 3 中实现 引入了对属性字典的改进处理 有效减少了类实例的内存占用 slots http docs python org 3