【问题标题】:Efficient small byte-arrays in C#C# 中的高效小字节数组
【发布时间】:2017-12-11 00:30:27
【问题描述】:

我有大量非常小的对象。为了确保数据存储得非常紧凑,我重写了该类以将所有信息存储在具有可变字节编码的字节数组中。这数百万个对象中的大多数实例只需要 3 到 7 个字节来存储所有数据

在进行内存分析后,我发现这些字节数组总是占用至少 32 个字节

有没有办法比字节[] 更紧凑地存储信息?指向非托管数组会更好吗?

class MyClass
{
    byte[] compressed;

    public MyClass(IEnumerable<int> data)
    {
        compressed = compress(data);
    }

    private byte[] compress(IEnumerable<int> data)
    {
        // ...
    }

    private IEnumerable<int> decompress(byte[] compressedData)
    {
        // ...
    }

    public IEnumerable<int> Data { get { return decompress(compressed); } }
}

【问题讨论】:

  • 我添加了代码。我必须存储一些非常小的整数——因此是可变字节编码。
  • 部分问题是对象开销,这在 64 位构建中更糟。这有一些关于此的信息:Of Memory and Strings
  • 数组很好——我实际上包含了我期望的长度。内存分析器告诉我,长度为 3 的 byte[]-array 有效地占用了内存中的 32 个字节。
  • 这可能很简单,并且使用更少的内存来为您的小对象使用 longs,而无需费心创建一个类。您可以编写用于打包/解包的扩展方法。这将避免对象开销。
  • 或者您可以定义一个结构,该结构只有一个长值成员,并且在该结构中具有用于打包/解包的方法。

标签: c# arrays memory encoding compression


【解决方案1】:

您面临的几个问题会占用内存。一个是对象开销,另一个是对齐到 32 位或 64 位边界的对象(取决于您的构建)。您当前的方法存在这两个问题。以下来源对此进行了更详细的描述:

我在fiddling with benchmarking sizes 时玩过这个。

一个简单的解决方案是简单地创建一个结构,该结构具有一个长值成员。它的方法将使用移位和掩码位摆弄处理将字节打包和解包进出那个长。

另一个想法是通过 ID 提供对象的类,并将实际字节存储在单个支持 List&lt;byte&gt; 中。但这会变得复杂和混乱。我认为 struct 的想法要简单得多。

【讨论】:

  • 我对一个大的后备数组只存储索引有很多看法——但就像你说的:它会很乱。
猜你喜欢
  • 2018-01-31
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 2011-02-07
相关资源
最近更新 更多