【问题标题】:Tuple<int, int> versus int[2] memory usageTuple<int, int> 与 int[2] 内存使用情况
【发布时间】:2011-01-13 15:10:53
【问题描述】:

有人知道这两者之间的内存差异吗?或者如何自己轻松解决?

【问题讨论】:

    标签: .net


    【解决方案1】:

    对于 32 位 CLR,两者都有 4 个字节用于锁定,4 个字节用于类型句柄,8 个字节用于两个整数。但是,该数组将有额外的 4 个字节来存储长度(在本例中为 2 个),因此该数组将有 4 个字节的开销。

    32 位上的大小(由分析确定):
    Tuple&lt;int, int&gt;:16 字节
    int[2]:20 字节
    int[1 to 2]*:28 字节
    int[2, 1]:36字节
    在 64 位 CLR 上:
    Tuple&lt;int, int&gt;:24 字节
    int[2]:32 字节
    int[1 to 2]*:40 字节
    int[2, 1]:48 字节

    请注意,值类型的从零开始的一维数组是可能的最小数组。使用引用类型为要存储的对象类型增加了另外 4 个字节(64 位为 8 个字节)。使用非零数组基数或多维使其使用另一种存储排名和下限信息的数组类型,每维增加 8 个额外字节。

    参考资料:

    * 你不能在 C# 中声明具有非 0 下限的数组,所以我编写了语法 int[1 to 2]。但是,您可以调用 Array.CreateInstance(typeof(int), new[]{2}, new[]{10}); 创建一个包含 2 个元素的数组,索引为 10 和 11。当然,由于此类数组不能直接在 C# 的类型系统中表示,它们并不是非常有用,但它们提供了一个有趣的数据点.

    【讨论】:

    • 数组是一种特殊情况,即使是经过 IL 优化的数组也是如此,因此它们在 CLI 本身中有额外的开销。
    【解决方案2】:

    Tuple&lt;int, int&gt; 使用与具有两个整数字段的类相同的内存。另一方面,一个数组有一个相当大的内部数据结构(在SSCLI 中称为ArrayOpScript),它至少有32 个字节加上每个等级的另一个数据结构(称为ArrayOpIndexSpec)(在本例中为一个) 大小为 16 个字节。因此,几乎可以肯定,数组使用的内存比Tuple 多几个因素。

    【讨论】:

    • 我在 .Net 4 CLR 上的分析表明,即使是多维数组也只比 2-int 类大 20 或 24 个字节。
    • 我应该先测量它,而不是试图推理和推测。我的测量结果显示,在 .NET4 x86 CLR 中,int[2] 仅比 Tuple 消耗约 20% 的内存,这与您的回答一致。
    猜你喜欢
    • 2018-01-16
    • 2011-06-07
    • 2015-12-10
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    相关资源
    最近更新 更多