我有大量的字符串列表。我想保留这些列表以提高内存效率。我试图保留一份清单。但是,它为具有5个字符的每个字符串使用24个字节。即,应该有一些开销区域。
然后,我尝试保留一个字符串数组。内存使用效率很高。但是,我仍然有内存使用问题。
如何保存字符串列表?我知道“ C#为每个字符保留2个字节”。我想保存一个具有5个字符的字符串,即5 * 2 = 10个字节。但是,为什么要为此过程使用24个字节?
感谢您的帮助。
答案 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类型的字符,则可以将它们存储为字节数组,但每个数组仍会占用一些空间。
您最好的方法(我想这有点像评论)是想出不同的处理算法,这些算法不需要首先将它们全部同时存储在内存中。