.NET 字符串与流 - 内存配置文件和特征
Posted
技术标签:
【中文标题】.NET 字符串与流 - 内存配置文件和特征【英文标题】:.NET Strings vs. Streams - Memory Profile and Characteristics 【发布时间】:2010-09-28 16:13:18 【问题描述】:我需要从数据库 (nvarchar) 中提取大型 Unicode 文本字符串(例如 200Mb)并存储在内存中以进行处理。即我需要随机访问字符串的所有部分。
从严格以内存为中心的角度来看,使用 System.IO.MemoryStream 与 System.String 作为我的内存表示的优缺点是什么。
我正在尝试研究的一些因素是:
这些对象如何在 [假设的] 高度碎片化的低内存环境中发挥作用 不变性 内存中的实际大小 (如果流是 UTF8,我们是否几乎 减半) 还有其他我没有想到的对象吗?我正在寻找关于这些点的清晰和建议,以及我没有想到的任何其他记忆注意事项?
注意:处理这些字符串可能有更好的方法,但此时我只是询问存储此类对象的内存考虑。
【问题讨论】:
有源代码的好示例吗?? 【参考方案1】:从严格以内存为中心的角度来看,使用 System.IO.MemoryStream 与 System.String 作为我的内存表示的优缺点是什么。
我正在尝试研究的一些因素是:
这些对象如何在 [假设的] 高度碎片化的低内存环境中发挥作用
IMO,MemoryStream 仅在编码很简单(例如 ASCII、ISO-8859-X 等)时才有用。如果编码是 UTF-8 并且您有非 ASCII 字符,那么处理将变得更加困难。当然,MemoryStream 几乎肯定会消耗更少的内存,但除此之外没有太大区别。在底层,MemoryStream 使用字节数组,它也需要分配在连续的内存块中。
内存中的实际大小(如果流是 UTF8,我们是否将大小减半)
没错,使用纯 ASCII 字符,MemoryStream 将消耗等效字符串消耗的一半。
还有其他我没有想到的对象吗?
List<byte> // has a nicer interface for processing
字符串是如何存储在数据库中的? varchar 还是 nvarchar?
问候,
安德烈亚斯
【讨论】:
感谢 Andreas,字符串从数据库中以 nvarchar 形式出现。 你好安德烈亚斯。在 MSDN 上进一步阅读之后,我读到使用默认构造函数创建的 MemoryStream 是可调整大小的,因此这表明它不需要连续的内存块。这是一个公平的假设吗? 见:msdn.microsoft.com/en-us/library/… 在这种情况下,如果我没记错的话,那么使用 LINQ 或 ADO 就无法避免 System.String。所以至少当你加载数据时,你需要将整个字符串放入内存中。在进一步处理之前将其转换为字节数组 - 直到 GC 收集字符串 - 需要更多内存。 是的,通过 DataReader 可能是最好的。我猜你在多个块中读取 DB 字符串并将它们转换为 UTF-8,然后再将它们写入 MemoryStream,对吧?如果是这样,那么之前调用 MemoryStream.SetSize 将避免任何额外的分配和复制。【参考方案2】:字符串与流的内存相当无关紧要。字符串是 utf-16,因此可能会涉及一个小的倍数,但由于涉及的卷,您最好将数据写入暂存文件。
要从数据库中读取数据,请使用流技术;即使用 IDataReader (ExecuteReader),它处于顺序模式,并读取字节/字符块。不要试图阅读整列。
此外,对于 SQL Server 2008,您可能希望查看文件流类型。
例子:
reading 大块/块 writing 大块/块【讨论】:
以上是关于.NET 字符串与流 - 内存配置文件和特征的主要内容,如果未能解决你的问题,请参考以下文章