C# 管理StringBuilder资源

C# 管理StringBuilder资源,c#,performance,resources,stringbuilder,C#,Performance,Resources,Stringbuilder,我的C#(.NET2.0)应用程序有一个容量为2.5MB的StringBuilder变量。显然,我不希望每次填充时都将如此大的缓冲区复制到更大的缓冲区空间。到那时,缓冲区中有这么多数据,删除旧数据是一个可行的选择。有人能看到我在做这件事的过程中有什么明显的问题吗(比如,我引入的性能问题比我正在解决的要多),或者看起来还好吗 tText_c = new StringBuilder(2500000, 2500000); private void AppendToText(string te

我的C#(.NET2.0)应用程序有一个容量为2.5MB的StringBuilder变量。显然,我不希望每次填充时都将如此大的缓冲区复制到更大的缓冲区空间。到那时,缓冲区中有这么多数据,删除旧数据是一个可行的选择。有人能看到我在做这件事的过程中有什么明显的问题吗(比如,我引入的性能问题比我正在解决的要多),或者看起来还好吗

  tText_c = new StringBuilder(2500000, 2500000);

  private void AppendToText(string text)
  {
     if (tText_c.Length * 100 / tText_c.Capacity > 95)
     {
        tText_c.Remove(0, tText_c.Length / 2);
     }

     tText_c.Append(text);
  }
编辑:其他信息:


在这个应用程序中,通过串行连接可以非常快速地(以毫秒为单位)接收新数据。我不想如此频繁地用这些新信息填充多行文本框,因为这会降低应用程序的性能,所以我将它保存到
StringBuilder
。每隔一段时间,应用程序就会将
StringBuilder
的内容复制到文本框中,并清除
StringBuilder
的内容。

您实际如何使用此
StringBuilder
?事实上,你正在从中移除一些东西,这表明你真的在把它当作一种缓冲

请注意,像这样调用
Remove
已经将缓冲区的后半部分复制到了前半部分,因此您仍在进行大量复制


您是否可以使用字符串的循环缓冲区,而不是使用
StringBuilder
?这将使它几乎可以自由地丢弃旧数据并用新字符串替换它。除了附加整个字符串和偶尔(可能)将整个字符串转换为单个字符串之外,您还需要对生成器执行任何操作吗?

您是否需要使用stringstream或memorystream?您可以根据需要写入流并从中读取

我可以看到让您的StringBuilder像那样变大会出现各种各样的问题,其中最重要的一点是它将位于大型对象堆上。

“…用于缓冲ASCII文本,以便稍后复制到多行文本框中…”

当您超过~200kb时,您的文本框将发生痉挛…它不会失败…但它的性能会像石头一样下降。使用某种类型的字符串集合的控件可能是更好的主意…可能是ListBox?…伪示例:

public void AddText(string text){
  ListBox.items.add(text);
  if(ListBox.items.count > 4096){
    ListBox.items[0].remove();
  } 
}
“。需要更新(每秒数百次,如果不是数千次)并重新绘制…”


您的Ui更新率没有合理地超过~50hz……可能会对您的缓冲区结构产生影响。

我能够通过分配一个足够大的缓冲区来存储足够的文本,以便在应用程序序列中进行一次传递(然后是一些传递),从而解决性能问题。每次序列(重新)启动时,缓冲区都会被清除。

这没有任何意义。StringBuilder中哪些内容不需要旧数据。请解释。。您想做什么?正在使用
StringBuilder
缓冲ASCII文本,以便稍后复制到多行文本框中。文本框并不总是需要更新(每秒数百次,如果不是数千次的话)和重画,这就是为什么我要将文本添加到
StringBuilder
@Jim fall:ok,听起来,字符串的循环缓冲区确实是一种更好的方式,甚至可能只是一个简单的缓冲区queue@Joel:如果想法是在数据太多时丢弃数据,那么循环缓冲区比队列更容易做到。@Jon:谢谢你的想法。我开始实现一个循环缓冲区,但当我开始实现它时,我意识到我将进行与当前实现相同的复制(如果不是更多的话)。Joel,你能提供(或链接到)一个
StringStream
的示例吗?我发现<代码>内存流,但我可以说,它只允许固定的缓冲区大小。@吉姆-我用C++的日子混淆了<代码> So.IO。StReLeLeave/Cuff>。至于memorystream,它确实有一个固定的缓冲区,但它的想法是,因为它是一个流,所以当您从中读取时,缓冲区会被清除。现在,为了(我的)时间,我正在考虑使用我原来的方法,除了缓冲区将被清除90%-95%,因此只需要复制5%-10%。