为什么命名元组使用的内存比字典少?

2024-01-03

我问这个是因为我觉得这很令人惊讶——我想namedtuple会有更多的开销。

(背景是我在内存中缓存了一个大型 Django 查询,发现 Django 对象的大小是.values()。然后我想知道什么开销namedtuple对象的版本将是,允许我仍然使用.访问作为属性的项目。更小不是我所期望的。)

#!/usr/bin/env python                                                           

from pympler.asizeof import asizeof                                             
from collections import namedtuple                                              

import random                                                                   
import string                                                                   

QTY = 100000                                                                    


class Foz(object):                                                              
    pass                                                                        

dicts = [{'foo': random.randint(0, 10000),                                      
          'bar': ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(32)]),
          'baz': random.randrange(10000),                                       
          'faz': random.choice([True, False]),                                  
          'foz': Foz()} for _ in range(QTY)]                                    

print "%d dicts: %d" % (len(dicts), asizeof(dicts))                             

# https://stackoverflow.com/questions/43921240/pythonic-way-to-convert-dictionary-to-namedtuple-or-another-hashable-dict-like

MyTuple = namedtuple('MyTuple', sorted(dicts[0]))                               

tuples = [MyTuple(**d) for d in dicts]                                          

print "%d namedtuples: %d" % (len(tuples), asizeof(tuples))                     

print "Ratio: %.01f" % (float(asizeof(tuples)) / float(asizeof(dicts))) 

Running,

$ ./foo.py    
100000 dicts: 75107672
100000 namedtuples: 56707472
Ratio: 0.8

单个元组甚至更少,可能是由于list:

$ ./foo.py    
1 dicts: 1072
1 namedtuples: 688
Ratio: 0.6

是哈希表数组的开销吗?但不会是namedtuple还需要属性的哈希表吗?是pympler不准确吗?


基本答案很简单:“是”:普通对象有一个内部字典来存储实例的属性:

class Foo:
    pass

f = Foo()
print(f.__dict__)
# {}

它必须是一个字典,因为在 Python 中,您可以在类未定义的实例上分配新属性:

f.a = 1
print(f.__dict__)
# {'a': 1}

使用字典可以快速进行属性查找,但由于数据结构本身存在内存开销。另外,由于不同的实例Foo可能定义了不同的属性,每个实例可能需要自己的字典:

g = Foo()
print(g.__dict__)
# {}
print(f.__dict_ == g.__dict__)
# False

A namedtuple不允许在运行时添加属性。一个具体实例namedtuple因此,可以将其所有属性存储在由所有实例共享的单个实例中。

Given a namedtuple和一个实例:

Foo = collections.namedtuple("Foo", 'a,b')
f = Foo(1,2)

The namedtuple-构造函数产生 https://github.com/python/cpython/blob/12083284c54be25abadd85781d36b63731dc1f0c/Lib/collections/__init__.py#L458 a 描述符 https://stackoverflow.com/a/3798882/2722968对于每个字段并将其存储在类中;这里是存储命名属性和元组索引之间的转换的位置。当您访问属性时a实例f,属性访问通过此描述符进行路由:

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

为什么命名元组使用的内存比字典少? 的相关文章

随机推荐

  • jquery 插件在其他公共函数中调用公共函数

    我定义了我的插件基于http docs jquery com Plugins Authoring http docs jquery com Plugins Authoring function var methods init functi
  • 使用 httplib 进行不完整读取

    我在从特定网站获取 RSS 提要时一直遇到问题 我最终编写了一个相当丑陋的程序来执行此功能 但我很好奇为什么会发生这种情况以及是否有更高级别的接口正确处理此问题 这个问题并不是真正的问题 因为我不需要经常检索提要 我已经阅读了一个捕获异常并
  • AngularJS Protractor E2E 模拟

    我有一个 Angular SPA 从节点后端检索其数据 由于节点项目完全覆盖了测试 我想模拟 Angular HTTP 调用 我不想开始讨论一般的功能 冒烟测试 谢谢 我想要的是 像这样 Api injector get Api sinon
  • 按位 XOR(异或)是什么意思?

    我试图理解 C 或一般情况下的二元运算符 特别是 异或 http msdn microsoft com en us library zkacc7k1 aspx 例如 给定一个正整数数组 除了一个出现奇数次的数字外 所有数字都出现偶数次 在
  • nodejs socket.io 在函数循环内发出

    我想通过循环内的 socket io 发出 为此 我制作了一个运行良好的触发器 但在每个触发器中我调用 socket emit 并且只有第一个发出有效 这是服务器代码 var server require http createServer
  • 从动态 PHP 页面生成 HTML 静态页面 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个脚本来在运行时从动态内容生成静态 HTML 页面 我基本上想做的就是保存那些缓存那些ht
  • 用于提取 HTML 图像属性的正则表达式

    我需要一个正则表达式模式来提取图像标签的所有属性 众所周知 存在大量格式错误的 HTML 因此该模式必须涵盖这些可能性 我正在看这个解决方案https stackoverflow com questions 138313 how to ex
  • 用于乐观更新的操作存储是 Redux/Flux 中的一个好方法吗?

    我一直在 React Flux 应用程序中进行乐观更新 并看到了两件事 如果用户在存在某些未完成的操作时尝试关闭窗口 会发生什么情况 例如 在 Facebook 中 即使没有真正持久化 消息也会出现在墙上 这就是乐观更新的作用 对用户来说是
  • flag_shih_tzu 可以处理的最大标志数量是多少?

    我正在使用 flag shih tzu gem 我想知道它可以处理的最大标志数量是多少 或者它是否取决于 int 标志列中的长度 我需要它来处理 64 个标志 can it 我是 flag shih tzu 的维护者 最佳实践 出于性能原因
  • 我是否正确使用了 Automapper 2.0 的 Include 功能?

    要么我没有 要么它不起作用 我有一个 Source 类 我想将其映射到彼此继承的多个视图 基本上 基类是 Detail 子类是 Edit 或 Update 它们使用与 Detail 相同的所有数据 再加上几个其他字段来管理自己的列表或其他内
  • 如何更改 allauth 中的电子邮件验证链接

    我在 django 应用程序中使用 allauth 创建用户后 它会发送一封包含如下链接的电子邮件http localhost 8001 account confirm email asdfafsd 不过 我希望链接是http localh
  • 通过 AlamofireImage 下载 UIImage? [复制]

    这个问题在这里已经有答案了 我有一个 URL 想通过返回函数下载图像 但是我无法让它正常配合 这是我的函数 func getTabImage url URL gt UIImage Alamofire request url response
  • 为多个客户端运行 Magento - 单个安装与多个安装

    我希望为多个客户端设置 Magento 社区版 安装 并且已经研究了几天这个问题 我可以看到企业版中有我需要的东西 但令人惊讶的是我不愿意支付每年 12 000 美元的订阅费用 似乎有一些选项可供选择 但我担心我将从各种选项中获得的性能 选
  • 删除 TensorFlow 图中除少数节点之外的所有节点

    我的 TensorFlow 用例要求我为每个需要处理的实例构建一个新的计算图 这最终会增加内存需求 除了少数几个tf Variables这些是模型参数 我想删除所有其他节点 其他有类似问题的人也发现了tf reset default gra
  • 如何在 Windows 中使用正则表达式匹配行尾

    我在 Windows 中创建了一个 txt 文件 现在应该在 Linux 中进行编辑 我想用 grep 匹配行尾 假设我要在文件中找到的行的内容是 foo bar bar 然后我发出命令grep r bar 但没有产生任何输出 在 Wind
  • 多线程 COMObject 和 UI 线程 (C#)

    这是我在这里发表的第一篇文章 因为实际上我通常用很棒的方法解决我所有的问题 您可以在这里找到邮政数据库 但我现在实际上陷入困境 我正在开发一个遵循 MVVM 的项目 其中包括一个 COM 对象 正如我在研究过程中所读到的那样 我了解到 CO
  • 具有多个代理的 Ember CLI

    问题 我有一个 Ember CLI 应用程序 它将使用多个 API 我需要在开发模式下代理这些 API 背景 我有一个遗留的 api 它在以下位置公开服务 api在我的本地开发机器上运行localhost 3000 我有一个新的 api 它
  • 申请家庭内如何分配?

    我有包含多个因素的 data frame 我想重命名所有这些因素的因素级别 例如 mydf lt data frame col1 as factor c A A NA NA col2 as factor c A NA NA A mydf l
  • 不同 Modelica 仿真环境之间有什么区别?

    有不同的 Modelica 仿真环境 包括 Dymola Wolfram SystemModeler OpenModelica 和 Jmodelica 所以 我尝试加载热流体库 ThermoSysProhttps github com Dw
  • 为什么命名元组使用的内存比字典少?

    我问这个是因为我觉得这很令人惊讶 我想namedtuple会有更多的开销 背景是我在内存中缓存了一个大型 Django 查询 发现 Django 对象的大小是 values 然后我想知道什么开销namedtuple对象的版本将是 允许我仍然