Jim Fell
Jim Fell

Reputation: 14256

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 information:

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.

Upvotes: 0

Views: 823

Answers (4)

Jim Fell
Jim Fell

Reputation: 14256

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.

Upvotes: 0

Rusty
Rusty

Reputation: 3268

"...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.

Upvotes: 1

Joel Coehoorn
Joel Coehoorn

Reputation: 415600

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.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499810

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?

Upvotes: 1

Related Questions