管理StringBuilder资源

时间:2010-05-25 13:36:11

标签: c# performance resources stringbuilder

My C#(.NET 2.0)应用程序有一个StringBuilder变量,容量为2.5MB。显然,我不希望每次填充时都将这么大的缓冲区复制到更大的缓冲区。到那时,缓冲区中有太多数据,删除旧数据是一个可行的选择。任何人都可以看到我这样做的任何明显问题(即我引入的性能问题比我解决的更多),还是看起来不错?

  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内容。

4 个答案:

答案 0 :(得分:1)

你是如何实际使用这个StringBuilder的?你从中删除东西的事实表明你真的把它当作一种缓冲区。

请注意,像这样调用Remove已经将缓冲区的后半部分复制到第一部分,因此您仍然需要进行大量复制。

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

答案 1 :(得分:1)

“...用于缓冲ASCII文本以便稍后复制到多行文本框。”

当你超过〜200kb时,你的文本框会有癫痫发作...它不会失败......但它的表现会像石头一样掉落。使用某种字符串集合的控件可能是一个更好的主意......也许是ListBox?...伪示例:

public void AddText(string text){
  ListBox.items.add(text);
  if(ListBox.items.count > 4096){
    ListBox.items[0].remove();
  } 
}

“..需要更新(数百,如果不是数千次,每秒一次)并重新绘制..”

你的Ui更新速率不会超过~50hz ......可能会对你的缓冲结构产生影响。

答案 2 :(得分:0)

你可能想要一个字符串流或内存流吗?您可以根据需要写入流并从中读取。

我可以看到让你的StringBuilder像这样变大的各种问题,其中最重要的是它会被放在大对象堆上。

答案 3 :(得分:0)

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