views:

3827

answers:

6

A recent question came up about using String.Format(). Part of my answer included a suggestion to use StringBuilder.AppendLine(string.Format(...)). Jon Skeet suggested this was a bad example and proposed using a combination of AppendLine and AppendFormat.

It occurred to me I've never really settled myself into a "preferred" approach for using these methods. I think I might start using something like the following but am interested to know what other people use as a "best practice":

sbuilder.AppendFormat("{0} line", "First").AppendLine();
sbuilder.AppendFormat("{0} line", "Second").AppendLine();

// as opposed to:

sbuilder.AppendLine( String.Format( "{0} line", "First"));
sbuilder.AppendLine( String.Format( "{0} line", "Second"));
+17  A: 

I view AppendFormat followed by AppendLine as not only more readable, but also more performant than calling AppendLine(string.Format(...)).

The latter creates a whole new string and then appends it wholesale into the existing builder. I'm not going to go as far as saying "Why bother using StringBuilder then?" but it does seem a bit against the spirit of StringBuilder.

Jon Skeet
Yep, I'll totally take this on (and thanks for taking me up on it in the first place, BTW).
Neil Barnwell
No problem - and sorry if my tone appeared gruff in the original comment. Multitasking does that to me sometimes :(
Jon Skeet
A: 

AppendFormat() is a lot more readable than AppendLine(String.Format())

Brian Genisio
A: 

I prefer this structure:

sbuilder.AppendFormat("{0} line\n", "First");

Though admittedly there is something to be said for separating out the line breaks.

Joel Coehoorn
I suppose "jinx" doesn't work on SO, does it?
Coderer
I tended to use \r\n, but I prefer Environment.NewLine which is awkward to use. Hence asking the question.
Neil Barnwell
A: 

Is it just positively awful to simply use

sbuilder.AppendFormat("{0} line\n", first);

? I mean, I know it's not platform-independent or whatever, but in 9 out of 10 cases it gets the job done.

Coderer
A: 

If performance is important, try to avoid AppendFormat() completely. Use multiple Append() or AppendLine() calls instead. This does make your code larger and less readable, but it's faster because no string parsing has to be done. String parsing is slower than you might imagine.

I generally use:

sbuilder.AppendFormat("{0} line", "First");
sbuilder.AppendLine();
sbuilder.AppendFormat("{0} line", "Second");
sbuilder.AppendLine();

Unless performance is critical, in which case I'd use:

sbuilder.Append("First");
sbuilder.AppendLine(" line");
sbuilder.Append("Second");
sbuilder.AppendLine(" line");

(Of course, this would make more sense if "First" and "Second" where not string literals)

Chris
What's your proof for the bad performance of AppendFormat?
Neil Barnwell
The benchmark I did showed a 5-times performance increase when using seperate Append() calls instead of a single AppendFormat() call with 4 arguments.
Chris
+6  A: 

String.format creates a StringBuilder object internally. By doing

sbuilder.AppendLine( String.Format( "{0} line", "First"));

an additional instance of string builder, with all of its overhead is created.


Reflector on mscorlib, Commonlauageruntimelibary, System.String.Format

public static string Format(IFormatProvider provider, string format, params object[] args)
{
    if ((format == null) || (args == null))
    {
        throw new ArgumentNullException((format == null) ? "format" : "args");
    }
    StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));
    builder.AppendFormat(provider, format, args);
    return builder.ToString();
}
AdamSane