首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >下载时内存优化

下载时内存优化
EN

Stack Overflow用户
提问于 2010-03-27 12:27:57
回答 2查看 152关注 0票数 2

你好,我有下面的代码,我期待着优化,因为我消耗大量内存,这个例程被大量使用

首先,优化将字符串生成器构造从下载例程中移出并使其成为类的字段,然后在例程中清除它。

请你提出任何其他优化,或指出我的方向,一些资源,可以帮助我(网页,书籍等)。

我正在考虑用一个固定(大得多)大小的缓冲区来替换字符串生成器.或者创建一个更大的字符串生成器。

提前谢谢。

StreamWriter \_writer; StreamReader \_reader; public string Download(string msgId) { \_writer.WriteLine("BODY <" + msgId + ">"); string response = \_reader.ReadLine(); if (!response.StartsWith("222")) return null; bool done = false; StringBuilder body = new StringBuilder(256\* 1024); do { response = \_reader.ReadLine(); if (OnProgress != null) OnProgress(response.Length); if (response == ".") { done = true; } else { if (response.StartsWith("..")) response = response.Remove(0, 1); body.Append(response); body.Append("\r\n"); } } while (!done); return body.ToString(); }

EN

回答 2

Stack Overflow用户

发布于 2010-03-27 12:44:35

使用固定大小的缓冲区实际上会使问题变得更糟,因为您必须选择一个比您可能填充的大小更大的大小。这个缓冲区每次都会被重新创建--或者如果你把它移到方法之外,每次创建类的时候。如果您将它保留为类属性,那么它将活到类存在的时间,而不仅仅是方法执行的时间长度。

只要您需要以字符串的形式返回结果,我就坚持使用StringBuilder。我唯一能想到的其他选择是将它改为使用过滤器流。也就是说,创建一个环绕当前使用的读取器的StreamReader,它像下载方法一样转换底层流。然后,消费类可以简单地使用您的StreamReader实现,您只需要处理每个块,而不是一次将整个内容保存在内存中。如果消费类需要所有的东西,这不会给你买多少钱,但我不知道你是如何使用它的。

票数 1
EN

Stack Overflow用户

发布于 2010-03-28 10:50:01

很难仅在此方法的上下文中提出建议,因为结果值是一个包含接收数据的全部内容的字符串.然而,该方法迟早会收集数据,但需要将其转换为单个字符数组。

这个方法的调用方是否真的需要每次内存中的整个响应,这可能是值得一问的问题;调用者是否可以一次一行地处理数据,以便一次只需要一行在内存中?(如果是这样的话,用yield语句实现的yield可能会工作得更好,而不会显着地改变方法的实现)

关于内存分配,请记住,并非所有内存分配都是在.NET中创建的;大小超过85 in的分配将被不同地对待,并且在频繁分配/释放时会导致内存碎片;参见:http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

如果碎片是您的主要问题,而且您一次只处理一个文档,那么创建一个共享缓冲区并保持它的分配可以帮助您解决一些问题,但是在假设它之前检查这是否是您的问题.修理没有坏的东西是浪费时间。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2529242

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档