Managing StringBuilder Resources
My C# (.NET 2.0) application has a StringBuilder variable with a capacity of 2.5MB. Obviously, I do not want to copy such a large buffer to a larger buffer space every time it fills. By that point, there is so much data in the buffer anyways, removing the older data is a viable option. Can anyone see any obvious problems with how I'm doing this (i.e. am I introducing more performance problems than I'm solving), or does it look okay?
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);
}
EDIT: Additional infor开发者_运维技巧mation:
In this application new data is received very rapidly (on the order of milliseconds) through a serial connection. I don't want to populate the multiline textbox with this new information so frequently because that kills the performance of the application, so I'm saving it to a StringBuilder
. Every so often, the application copies the contents of the StringBuilder
to the textbox and wipes out the StringBuilder
contents.
How are you actually using this StringBuilder
? The fact that you're removing stuff from it suggests you're really using it as a sort of buffer.
Note that calling Remove
like this will already be copying the second half of the buffer into the first, so you're still doing a lot of copying.
Instead of using a StringBuilder
, could you use a circular buffer of strings? That would make it almost free to discard old data and replace it with new strings. Do you need to do anything with the builder other than appending whole strings and occasionally (presumably) converting the whole thing into a single string?
"...is being used to buffer ASCII text to be later copied to a multiline text box.."
Your textbox is going to have a seizure when you get past ~200kb...it won't fail...but its performance will drop like a stone. A control that uses a string collection of some sort might be a better idea...maybe a ListBox ?...pseudo example :
public void AddText(string text){
ListBox.items.add(text);
if(ListBox.items.count > 4096){
ListBox.items[0].remove();
}
}
"..need to be updated (hundreds, if not thousands, of times a second) and redrawn.."
Your Ui update rate is not reasonably going to better than ~50hz...might have an effect on your buffer structures.
Do you maybe want a stringstream or memorystream instead? You can write into the stream and read from it as needed.
I can see all kinds of problems with letting your StringBuilder grow large like that, not the least of which is that it's gonna sit on the large object heap.
I was able to resolve the performance problems I was having by allocating a buffer large enough to store enough text for a single pass through the application sequence (and then some). Every time the sequence is (re)started, the buffers are cleared.
精彩评论