C#中一个小类的内存优化

Roo*_*bal 3 c# memory optimization

我有一段代码可以将一个大的字符串矩阵转换成一个大的MyClass. MyClass是我编写的一个小类,它存储有关每个字符串的一些信息,如下所示:

class MyClass
{
    public MyEnum Class { get; private set; }

    public int A { get; private set; }
    public int B { get; private set; }
    public int C { get; private set; }
    public int D { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)

目前该软件能够处理大至 5-20 列 x 100 万行的矩阵,但我希望将行数增加到接近 1000 万行。我不认为我可以做很多事情来减少字符串矩阵的占用空间,但我想减少MyClass.

我可以使用shortas 列的类型A以及, andbyte的类型,尽管这需要对代码进行相当大的重构。BCD

我的问题,或者更确切地说是问题:

  1. 是否值得重构代码以使用shortand byte?
  2. 我还应该重构MyEnum为类型吗byte?
  3. 我还能做些什么来提高课堂效率吗?

非常感谢您抽出时间!

编辑:更多上下文 - 的矩阵MyClass是从字符串矩阵创建的,以便进行分析。字符串矩阵是通过普通的网络连接从文本文件中提取出来的,因此将任务分割成更小的块并不理想。

Giu*_*nco 5

截至目前,假设您的所有属性都是通过实例变量实现的,并且您在 64 位计算机上运行,​​则 MyClass 的实例为 4B*4 + 8B = 24B。此外,由于您使用的是类(引用类型),因此 MyClass 的矩阵每个单元格的权重将为 8B。这意味着每个单元使用 32B。然后,MyClass 的 10Mx20 矩阵使用大约 6.4GB(对于这些大小,您必须使用 64 位二进制文​​件),它可能不止于此,因为我忽略了内存对齐要求。

如果从类切换到结构体(值类型),矩阵将直接存储 MyClass 实例,而不是指向 MyClass 实例的指针。因此,每个实例将节省 8B。现在,内存使用量下降至 4.8GB。

如果您进一步调整实例变量,使用 1 个短字节和 3 个字节,并将枚举转换为字节,则每个实例将仅使用 6B。因此,总内存使用量将下降至 1.2GB。

无论如何,它会不止于此,因为托管环境在每个对象中存储一些其他元数据,并且因为内存对齐需要填充对象以加快访问时间。

PS:您实际上不需要更改属性的返回类型。您可以封装类型更改,并在 MyClass 的实现中执行强制转换,例如:

struct MyClass
{
  private short a; //Also consider ushort, if you need it
  //...

  public int A
  {
    get { return a; //Automatic promotion }
    private set
    {
      a = (short) value;
      System.Diagnostics.Debug.Assert(a == value, "Integer overflow");
    }
  }

  //...
}
Run Code Online (Sandbox Code Playgroud)

这样,优化对于使用 MyClass 的代码来说是透明的。

  • 但请记住,单个对象的 2GB 限制。更改为“struct”会导致大小为 4.8 GB 的数组,在 .NET 4.5 和 [gcAllowVeryLargeObjects](http://msdn.microsoft.com/en-us/library 之前,无法用单个对象表示该数组/hh285054.aspx) (2认同)