views:

182

answers:

7

Hello,

I receive around 5 messages per second. Each of them has a string, which I concatenate to a master string that contains all the received messages

    string _masterText = "";
    public void AddNewMessage(string text)  // this is going to be call at least 5 times/second
    {
        _masterText += text;    
    }

Is this the appropiated way to do it? or should I use instead StringBuilder, like:

    StringBuilder _masterText = new StringBuilder();
    public void AddNewMessage(string text) // this is going to be call at least 5 times/second
    {
         _masterText.Append(text);  
    }

Thanks

+3  A: 

Every 200ms isnt a very taxing poll, regardless stringbuilder is always better.

Dested
A: 

StringBuilder is your buddy!

Jaime
+13  A: 

StringBuilder is generally considered the better option, but in this case I'd use neither.

Even with StringBuilder, at that rate the underlying character buffer will soon itself be large enough to get stuck on the Large Object Heap. This will cause problems for the health of an application that needs to stay running for a while.

Instead, I'd use a System.Collections.Generic.List<string> and just call it's .Add() method for each new message. Depending on what you do with these messages you may also find another collection type is more appropriate (perhaps a Queue<string>), but this is the direction you should go.

Joel Coehoorn
It would also be a good idea to dump the messages to disk every hour or so to keep memory usage at a sane level. Depending on how important these messages are you may want to have a dedicated thread managing the storage of the messages.
ChaosPandion
this is not going to run during all day, the user will launch the application and will be running for 5 minutes at most
pedroruiz
@pedroruiz okay, that's fine. List and Queue are still easier and faster, and still the correct way to handle this.
Joel Coehoorn
@pedroruiz - My comment would of course be ridiculous overkill.
ChaosPandion
+6  A: 

Remember that the String class is immutable. It is not possible to change a string. When you are "concatenating" strings, you are really creating a new string, and copying the contents of the original string to it, then adding the contents of your new string.

This starts to use memory very quickly if you're appending large strings.

John Saunders
Especially once each intermediate string takes up 80,000 bytes and goes right to the LOH.
Joel Coehoorn
A: 

Good compilers will generate the exact same bytecode for both methods. The difference is in the way you are initializing your StringBuilder, you should always initialize your StringBuilder with the aproximate bytes you will be concatenating, otherwise there is really no performance gain. The size grows by double everytime, so it is better to initialize high.

Also take into consideration if you go the StringBuilder route, you won't be able to use the new optimizations with the + that may or may not come up later on.

OscarMk
@OscarMk: -1: string concatenation is totally different IL from StringBuilder. He's talking about .NET - are you talking about Java?
John Saunders
@John Saunder : Yes I was talking about java, sorry I though this was a Java question.
OscarMk
A: 

If you're up for a read, I think the discussion at http://dotnetperls.com/stringbuilder-1 is really useful. Check out the links to real metrics on speed and memory usage.

Also, check out Joel Spolsky's discussion of "Shlemeil the Painter's Algorithm". Although he's talking about C's strcat function, the principle applies to C#'s plus operator on strings. Besides, it's good for a laugh.

In general, I recommend StringBuilder if you are doing the append operation rapidly or with many large strings.

kbrimington
A: 

It depends upon the scenario as well. No doubt it is faster to add with the generic list as compare to the stringbuilder object. But during the time of data retrieval from the generic list, it will be much slower as compare to the stringbuilder object.

The stringbuilder will return quickly using _masterText.ToString() but with the generic list, you might have to pull the value using the iteration. And that will be expensive process such as :-

  for (int x = 0; x < 100; x++)
    {
      Label3.Text += gen_list[x];
    }

Or you can try with

Label3.Text = string.Join("", gen_list.ToArray());

then the retrieval operation will be slower and expensive, and you can notice the CPU spike easily.

Karan