.NET 中泛型集合和非泛型集合之间的内存使用差异

2024-02-24

我读到收藏品如今在 .NET 中。众所周知,使用有一些优点通用集合 over 非通用的:它们是类型安全的,没有转换,没有装箱/拆箱。这就是通用集合具有性能优势的原因。

如果我们认为非泛型集合将每个成员存储为object,那么我们可以认为泛型也具有内存优势。但是,我没有找到任何有关内存使用差异的信息。

有人能澄清这一点吗?


如果我们考虑到非泛型集合将每个成员存储为对象,那么我们可以认为泛型也具有内存优势。但是,我没有找到任何有关内存使用差异的信息。有人能澄清这一点吗?

当然。让我们考虑一个ArrayList其中包含ints vs a List<int>。假设有 1000 个int每个列表中都有 s。

在这两种情况下,集合类型都是数组的薄包装——因此得名ArrayList。如果是ArrayList,有一个底层的object[]包含至少 1000 个装箱整数。如果是List<int>,有一个底层的int[]至少包含 1000 个ints.

为什么我说“至少”?因为两者都采用双倍满策略。如果您在创建集合时设置了集合的容量,那么它会为很多东西分配足够的空间。如果你不这样做,那么集合必须猜测,如果它猜测错误并且你需要更多容量,那么它的容量就会增加一倍。因此,最好的情况是,我们的集合数组的大小完全正确。最坏的情况是,它们的大小可能是所需大小的两倍;数组中可以容纳 2000 个对象或 2000 个整数。

但为了简单起见,我们假设我们很幸运,每个都有大约 1000 个。

首先,数组的内存负担是多少?一个object[1000]仅用于引用,在 32 位系统上占用 4000 字节,在 64 位系统上占用 8000 字节,指针大小。一个int[1000]无论如何占用4000字节。 (数组簿记还占用了一些额外的字节,但与边际成本相比,这些成本很小。)

因此,我们已经看到非通用解决方案可能会消耗两倍于数组的内存。那么数组的内容呢?

嗯,关于值类型的事情是它们存储在自己的变量中。除了用于存储 1000 个整数的 4000 字节之外,没有额外的空间;它们被直接打包到数组中。因此,对于一般情况,额外成本为零。

For the object[]在这种情况下,数组的每个成员都是一个引用,并且该引用引用一个对象;在本例中,是一个装箱整数。装箱整数的大小是多少?

未装箱的值类型不需要存储有关其类型的任何信息,因为其类型由其所在存储的类型确定,并且运行时已知这一点。装箱值类型需要在某个地方存储框中事物的类型,这会占用空间。事实证明,32 位 .NET 中对象的簿记开销为 8 个字节,而在 64 位系统上为 16 个字节。这只是开销;我们当然需要 4 个字节来存储 int。但是等等,情况变得更糟:在 64 位系统上,盒子必须与 8 字节边界对齐,所以我们需要another64 位系统上的 4 字节填充。

全部加起来:我们的int[]在 64 位和 32 位系统上大约需要 4KB。我们的object[]包含 1000 个整数在 32 位系统上大约需要 16KB,在 64 位系统上大约需要 32K。所以内存效率int[] vs an object[]对于非通用情况来说,情况要糟糕 4 到 8 倍。

但等等,情况会变得更糟。这只是尺寸。访问时间怎么样?

要访问整数数组中的整数,运行时必须:

  • 验证数组是否有效
  • 验证索引是否有效
  • 从给定索引处的变量中获取值

要从装箱整数数组中访问整数,运行时必须:

  • 验证数组是否有效
  • 验证索引是否有效
  • 从给定索引处的变量中获取引用
  • 验证引用不为空
  • 验证引用是否是装箱整数
  • 从框中提取整数

步骤要多得多,因此需要更长的时间。

但等等,情况会变得更糟。

现代处理器使用芯片本身的缓存来避免返回主内存。 1000 个普通整数的数组很可能最终出现在高速缓存中,因此对快速连续的第一个、第二个、第三个等数组成员的访问都是从同一高速缓存行中提取的;这是快得离谱。但是装箱整数可能遍布整个堆,这会增加缓存未命中率,从而进一步大大减慢访问速度。

希望这足以澄清您对拳击处罚的理解。

非盒装类型怎么样?字符串数组列表和字符串数组列表之间有显着差异吗?List<string>?

这里的惩罚要小得多,因为object[] and a string[]具有相似的性能特征和内存布局。在这种情况下,唯一的额外惩罚是(1)直到运行时才发现错误,(2)使代码更难以阅读和编辑,以及(3)运行时类型检查的轻微惩罚。

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

.NET 中泛型集合和非泛型集合之间的内存使用差异 的相关文章

  • 如何使用 C# 以编程方式编辑 Power BI Desktop 文档参数或数据源?

    我有一个在 Power BI Desktop 中内置的报告模板 并保存为 pbix 或 pbit 文件 该模板使用DirectQuery SQL数据库作为数据源 而服务器地址和数据库名称被提取到参数中 还有一个参数包含一个ReportId
  • 具有多个谓词的 C++11 算法

    功能如std find if来自algorithmheader 确实很有用 但对我来说 一个严重的限制是我只能为每次调用使用 1 个谓词count if 例如给定一个像这样的容器std vector我想同时应用相同的迭代find if 多个
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • 类中是否可以有虚拟类声明?

    我正在为个人项目中框架的各个组件设置一个接口 我突然想到了一些我认为可能对接口有用的东西 我的问题是这是否可能 class a public virtual class test 0 class b public a public clas
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • PrivateObject 找不到属性

    我的结构基本上如下所示 abstract class A protected string Identificator get set private void DoSomething DoSomethingSpecific protect
  • 检测 TextBox 中的 Tab 键按下

    I am trying to detect the Tab key press in a TextBox I know that the Tab key does not trigger the KeyDown KeyUp or the K
  • 为什么 std::function 不是有效的模板参数,而函数指针却是?

    我已经定义了名为的类模板CallBackAtInit其唯一目的是在初始化时调用函数 构造函数 该函数在模板参数中指定 问题是模板不接受std function作为参数 但它们接受函数指针 为什么 这是我的代码 include
  • 如何增加ofstream的缓冲区大小

    我想增加 C 程序的缓冲区大小 以便它不会过于频繁地写入 默认缓冲区是 8192 字节 我尝试使用 pubsetbuf 将其增加到 200K 原始代码 ofstream fq fastq1 cstr ios out fastq1 is a
  • 如何设置消息队列的所有者?

    System Messaging MessageQueue 类不提供设置队列所有权的方法 如何以编程方式设置 MSMQ 消息队列的所有者 简短的答案是 p invoke 对 windows api 函数的调用MQSetQueueSecuri
  • 将 2 个字节转换为整数

    我收到一个 2 个字节的端口号 最低有效字节在前 我想将其转换为整数 以便我可以使用它 我做了这个 char buf 2 Where the received bytes are char port 2 port 0 buf 1 port
  • WinForms - 加载表单时如何使用 PaintEventArgs 运行函数?

    我试图理解图形 在 Graphics FromImage 文档中 它有这样的示例 private void FromImageImage PaintEventArgs e Create image Image imageFile Image
  • 在 mvc4 中创建通用 mvc 视图

    我以前也提过类似的问题 没有得到答案 如何创建一个通用的 mvc4 视图 该视图可以显示传递给它的模型列表或单个模型 模型可以是个人 组织或团体 无论传递给它的是什么 如果您正在寻找类似的东西 model MyViewModel
  • WPF DataGrid - 在每行末尾添加按钮

    我想在数据网格的每一行的末尾添加一个按钮 我找到了以下 xaml 但它将按钮添加到开头 有人知道如何在所有数据绑定列之后添加它吗 这会将按钮添加到开头而不是末尾
  • 用数组或向量实现多维数组

    我想使用单个数组或向量实现多维数组 可以像通常的多维数组一样访问它 例如 a 1 2 3 我陷入困境的是如何实施 操作员 如果数组的维数为 1 则 a 1 应该返回位于索引 1 处的元素 但是如果维数大于一怎么办 对于嵌套向量 例如 3 维
  • 将日期时间显示为 MM/dd/yyyy HH:mm 格式 C#

    在数据库中 日期时间以 MM dd yyyy HH mm ss 格式存储 但是 我想以 MM dd yyyy HH mm 格式显示日期时间 我通过使用 String Format 进行了尝试 txtCampaignStartDate Tex
  • MSVC编译器下使用最大成员初始化联合

    我正在尝试初始化一个LARGE INTEGER在 C 库中为 0 确切地说是 C 03 以前 初始化是 static LARGE INTEGER freq 0 在 MinGW 下它产生了一个警告 缺少成员 LARGE INTEGER Hig
  • 在实现使用原始类型的接口时如何避免警告?

    我正在实施流程工厂 http help eclipse org ganymede index jsp topic org eclipse platform doc isv reference api org eclipse debug co
  • 如何在c中断言两个类型相等?

    在 C 中如何断言两种类型相等 在 C 中 我会使用 std is same 但搜索 StackOverflow 和其他地方似乎只能给出 C 和 C 的结果 在C中没有办法做到这一点吗 请注意 这不是询问变量是否具有某种类型 而是询问两个类
  • 是否可以使用 Dapper 流式传输大型 SQL Server 数据库结果集?

    我需要从数据库返回大约 500K 行 请不要问为什么 然后 我需要将这些结果保存为 XML 更紧急 并将该文件通过 ftp 传输到某个神奇的地方 我还需要转换结果集中的每一行 现在 这就是我正在做的事情 TOP 100结果 使用 Dappe

随机推荐

  • UIImageWriteToSavedPhotosAlbum 保存为错误的尺寸和质量

    我正在尝试拍摄应用程序当前视图的屏幕截图并将其保存到相册 然后通过电子邮件或彩信发送 UIGraphicsBeginImageContext self view bounds size self view layer renderInCon
  • extjs 与 Node.js 后端?

    是否有任何项目 示例 教程等可以展示 ExtJS 与 Node js 作为后端的使用 我正在专门研究多个用户的实时协作 但任何将 ExtJS 和节点结合在一起的东西都会有所帮助 Here http www alsonkemp com gee
  • Elixir 或 Erlang 程序可以编译为独立的二进制文件吗?

    它说 Elixir 有一个工具叫做elixircErlang 有一个工具叫做erlc to 编译模块 http elixir lang org crash course html elixir用来 在此之后 您可以立即运行代码elixir命
  • 检测按下哪个键[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我如何知道
  • 未命中断点 Mono For Android (Monodroid)

    我的 monodroid 应用程序构建并运行良好 但未命中断点 这适用于物理设备和模拟器 我创建了一个新的默认 monodroid 应用程序 它确实遇到了断点 我尝试过重建 重新启动 ADB 和重新启动 我运行的是 VS2010 M4A 版
  • Firebase Google Cloud 从设备到设备的消息传递

    我无法理解如何将消息从 iOS 设备发送到另一台 iOS 设备 并试图了解两者之间的区别 Firebase 通知和 Google Cloud Messaging Firebase 通知假设您可以从服务器向设备发送消息 谷歌云消息 它将消息从
  • ElasticSearch:根据字段长度过滤文档

    我在 SO 上读到了几个类似的问题 并建议解决方案不起作用 我想找到单词短于8的所有字段 我的数据库屏幕 我尝试使用此查询来执行此操作 query match all filter script script doc word length
  • Cordova iOS 6.1.1 白色启动画面

    在我的 Cordova 应用程序中 升级到 cordova ios 6 1 1 后遇到问题 应用程序运行正常 但未显示启动屏幕 只有一个白屏 就像我的闪屏文件被忽略一样 我有这个 config xml 文件
  • 如何处理`已被弃用。在 Java 中已弃用?

    我想使用的代码 window addFlags WindowManager LayoutParams FLAG SHOW WHEN LOCKED 有FLAG SHOW WHEN LOCKED https developer android
  • 关闭 OpenMP

    在我的 C 程序中 我希望有时使用 OpenMP 有时不使用 OpenMP 即多线程或单线程 来运行其可执行文件 我正在考虑以下两种情况中的任何一种 我的代码如何使用 OpenMP 1 假设我的代码只有 include
  • 无法为 jasmine 设置超时

    我已经尝试了所有解决方案这个答案 https stackoverflow com questions 9867601 how do i change the timeout on a jasmine node async spec但他们都不
  • Spring Mvc 中从控制器返回 Hashmap 到 JSP

    我在 Jsp 中有两个下拉列表 一个用于州 另一个用于国家 一旦我选择国家 地区 国家列表就会自动填充相应的列表 但我得到整个 jsp 页面作为 ajax 调用的响应 我的ajax程序 select country change funct
  • 为什么图像没有保存在我的代码中而只是由管理页面保存?

    我需要知道为什么图像不保存在路径中 我从路径中检查 静态根和媒体根似乎都工作良好 但图像未保存 这里是代码 您可以在其中看到发生了什么 notice 该图像工作正常 并已通过管理页面安装 但无法保存或通过我的代码工作 模型 py class
  • Power Query M - 表达式错误 - 列表到文本

    我正在使用 Web Contents 执行 API 请求 我提交了一个从函数获取的动态访问令牌 let Source Json Document Web Contents https api url com endpoint id Head
  • 捕获蓝牙远程快门事件

    我想知道如何 是否可以在 android 中捕获由蓝牙远程快门事件触发的事件 例如这样的一个 http www avancaproducts com en shop other bluetooth camera shutter remote
  • 在 docker 中运行 json-server

    我一直在跑步json 服务器 https github com typicode json server使用以下配置在 docker 容器中成功运行了一段时间 泊坞窗文件 FROM node alpine EXPOSE 3000 COPY
  • 在自定义 UIGestureRecognizer 中实现速度

    我编写了一个自定义 UIGestureRecognizer 它可以用一根手指处理旋转 它的设计工作方式与 Apple 的 UIRotationGestureRecognizer 完全相同 并返回相同的值 现在 我想实现速度 但我无法弄清楚苹
  • 我应该使用 XSD 1.1 来构建开放标准吗?

    我们被要求为开放 XML 标准整合一组模式 XSD 1 0 可以处理大多数规则 但在某些地方会有点混乱 特别是考虑到可扩展性 它还依赖于实现者以注释的形式阅读某些规则的自由文本描述 几乎所有规则都可以使用 XSD 1 1 来实现 但是我们不
  • Java不发送客户端证书

    我在 Java 1 7 上使用 HttpClient 4 2 3 连接到 nginx 托管的远程服务器 我的组织广泛使用 PKI 并且远程和客户端都具有由通用 CA 颁发的证书 服务器有一个如下的签名链 CN Server 123 OU S
  • .NET 中泛型集合和非泛型集合之间的内存使用差异

    我读到收藏品如今在 NET 中 众所周知 使用有一些优点通用集合 over 非通用的 它们是类型安全的 没有转换 没有装箱 拆箱 这就是通用集合具有性能优势的原因 如果我们认为非泛型集合将每个成员存储为object 那么我们可以认为泛型也具