如何尽可能有效地保存字符串列表(内存)?

时间:2019-02-08 07:57:41

标签: c# arrays list memory-management

我有大量的字符串列表。我想保留这些列表以提高内存效率。我试图保留一份清单。但是,它为具有5个字符的每个字符串使用24个字节。即,应该有一些开销区域。

然后,我尝试保留一个字符串数组。内存使用效率很高。但是,我仍然有内存使用问题。

如何保存字符串列表?我知道“ C#为每个字符保留2个字节”。我想保存一个具有5个字符的字符串,即5 * 2 = 10个字节。但是,为什么要为此过程使用24个字节?

感谢您的帮助。

enter image description here

2 个答案:

答案 0 :(得分:6)

首先,请注意,以正确大小创建的List<string> 与(相同大小)string[]之间的区别对于任何非琐碎的大小List<T>实际上只是T[]的精美包装器,具有插入/调整大小/等功能。如果只需要保留数据:T[]很好,但通常List<T>也是如此。

对于字符串-不是C#保留任何内容-是.NET定义string是对象,内部是长度(int)加上{ {1}}数据,每个char 2个字节。但是:.NET中的对象具有对象标头,填充/对齐等,并且重要的是: 最小大小 。因此,是的,它们占用的内存比您要表示的原始数据还要多。

如果您只需要实际数据,则可能不将数据存储为char而不是string或{{1 }},或成对的byte[] / byte*(用于页面的长度和/或偏移量)和int[] / int*(用于实际字符数据) ),或者char[] / char*(如果您可以使用编码数据(即,您主要对IO工作感兴趣))。但是,使用这种形式会很不方便 -除非您在byte[]中交谈,否则几乎没有通用的API会希望与您一起玩。有一些 API可以接受原始字节/字符数据,但是它们主要是编码器/解码器API和某些IO API。再说一遍:除非那是你在做的:它不会很好地结束。最近,出现了一些byte* / string API,这些API会使 less 不太方便(如果可以使用最新的.NET Core构建等),但是:强烈怀疑在大多数情况下,您将只需要承担Span<char>开销并忍受。

答案 1 :(得分:2)

64位.NET中任何对象的最小大小为24个字节。

在32位中,它稍小一些,但对象标头总是至少有8个字节,在这里,我们希望字符串存​​储它的 length (4个字节)。 8 + 4 + 10 =22。我猜它也希望/需要将所有对象对齐4字节。因此,如果将它们存储为对象,则不会获得更小的表示形式。

如果所有字符都是7位ASCII类型的字符,则可以将它们存储为字节数组,但每个数组仍会占用一些空间。

您最好的方法(我想这有点像评论)是想出不同的处理算法,这些算法不需要首先将它们全部同时存储在内存中。