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

问题描述 投票:1回答:2

我有一个巨大的字符串列表。我想把这些列表保存为内存效率。我试图抓住一个清单。但是,它为每个包含5个字符的字符串使用24个字节。也就是说,应该有一些开销区域。

然后,我试着抓住一个字符串数组。内存使用率有点高效。但是,我还有内存使用问题。

我怎么能拿一个字符串列表?我知道“C#为每个字符保留2个字节”。我想要一个包含5个字符的字符串,如5 * 2 = 10个字节。但是,为什么它在这个过程中使用24个字节?

谢谢你的帮助。

enter image description here

c# arrays list memory-management
2个回答
6
投票

首先,请注意,以正确尺寸创建的List<string>string[](相同大小)之间的差异对于任何非平凡的大小都是无关紧要的; List<T>实际上只是T[]的一个奇特的包装器,具有插入/调整大小/等功能。如果你只需要保存数据:T[]很好,但通常是List<T>

至于字符串 - 它不是C#保留任何东西 - 它是.NET定义一个string是一个对象,它在内部是一个长度(int)加上char数据的内存,每个char 2个字节。但是:.NET中的对象具有对象标题,填充/对齐等 - 而且重要的是:最小大小。所以,是的,它们占用的内存不仅仅是您尝试表示的原始数据。

如果您只需要实际数据,您可以将数据存储为string,而不是原始存储器 - 可以是简单的大型byte[]byte*,也可以是int[] / int*的双对(用于长度和/或偏移到页面中) )和char[] / char*(对于实际的字符数据),或byte[] / byte*,如果你可以使用编码数据(即你主要对IO工作感兴趣)。但是,使用这样的表格将非常不方便 - 除非你在string谈话,否则几乎没有普通的API会想和你一起玩。有些API接受原始字节/字符数据,但它们主要是编码器/解码器API和一些IO API。再说一次:除非你正在做的事情:它不会结束。最近,出现了一些Span<char> / Span<byte> API,这会使这个稍微不那么不方便(如果你可以使用最新的.NET Core版本等),但是:我强烈怀疑在大多数常见情况下你只需要接受string开销并与之共存。


2
投票

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

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

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

你最好的路线(我欣赏这一点是更多的评论)是提出不同的处理算法,不要求它们首先同时在内存中。

© www.soinside.com 2019 - 2024. All rights reserved.