【问题标题】:Determining the number of bytes used by a variable确定变量使用的字节数
【发布时间】:2011-02-02 07:40:09
【问题描述】:

我有以下数组:

byte[][] A = new byte[256][];

这个数组的每个元素都引用另一个数组。

A[n] = new byte[256];

但是,大多数元素都引用同一个数组。实际上,数组 A 只引用了两三个唯一的数组。

有没有一种简单的方法可以确定整个事物使用了多少内存?

【问题讨论】:

    标签: c# .net arrays memory-management


    【解决方案1】:

    如果您的问题是找出唯一一维数组的数量,您可以这样做:

    A.Distinct().Count()
    

    这应该是因为默认情况下数组的相等性适用于引用相等性。

    但也许您正在寻找:

    A.Distinct().Sum(oneDimArray => oneDimArray.Length) * sizeof(byte)
    

    当然,“变量使用的字节数”是一个不太精确的术语。特别是,上面的表达式没有考虑变量A的存储、锯齿状数组中的引用、开销、对齐等。

    编辑:正如 Rob 指出的,如果锯齿状数组可以包含 null 引用,您可能需要过滤掉它们。

    您可以使用(unsafe 上下文)估算将引用存储在锯齿状数组中的成本:

    A.Length * sizeof(IntPtr) 
    

    【讨论】:

    • 还需要空检查:(a.Distinct().Where(aa => aa != null).Sum(aa => aa.Length) * sizeof(byte)).Dump( );
    • 谢谢。 (好代码,顺便说一句。)我正在编写一个 Boyer-Moore 搜索算法并查看多级表以减少用于移位表和 Unicode 字符的内存量。它正在工作,但我不知道我节省了多少内存。因此,除了引用的数组之外,我还对 A 使用的字节感兴趣。我猜它每个项目有 4 或 8 个字节(取决于是 32 位还是 64 位版本)。看起来 C# 不能告诉我。
    • @Rob:在我的特殊情况下,没有元素会为空。
    • @Jonathan Wood:它可以在不安全的环境中;我试图通过编辑来回答这个问题。
    • @Ari:这超出了我的知识范围。如何使用只能在不安全上下文中使用的构造来编译它?
    【解决方案2】:

    我不相信有任何内置功能。

    很快就搞定了,不过还没有彻底测试过;

    void Main()
    {
        byte[][] a = new byte[256][];
        var someArr = new byte[256];
        a[0] = someArr;
        a[1] = someArr;
        a[2] = new byte[256];
        getSize(a).Dump();
    }
    
    private long getSize(byte[][] arr)
    {
        var hashSet = new HashSet<byte[]>();
        var size = 0;
        foreach(var innerArray in arr)
        {
            if(innerArray != null)
                hashSet.Add(innerArray);
        }
    
        foreach (var array in hashSet)
        {
            size += array.Length * sizeof(byte);
        }
        return size;
    }
    

    【讨论】:

      【解决方案3】:

      我只是修改了 Rob 的 getSize 方法以使用 Buffer 辅助类。

      private long getSize(byte[][] arr)
      {
          Dictionary<byte[], bool> lookup = new Dictionary<byte[], bool>();
      
          long size = 0;
      
          foreach (byte[] innerArray in arr)
          {
              if (innerArray == null || lookup.ContainsKey(innerArray)) continue;
              lookup.Add(innerArray, true);
              size += Buffer.ByteLength(innerArray);
          }
      
          return size;
      }
      

      【讨论】:

      • 我在调用 ByteLength() 时收到错误 Object must be an array of primitives.
      • @Jonathan Wood,innerArray 是字节数组,字节是原始类型。你在传递arr吗?还是您使用的是字节以外的类型?
      • 是的,你是对的。它只适用于普通的 byte[] 数组。对于一个字节[256],它返回(惊喜)256。
      猜你喜欢
      • 1970-01-01
      • 2017-05-25
      • 1970-01-01
      • 2017-01-02
      • 1970-01-01
      • 2016-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多