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