8
string str = 'my {0} long string {1} need formatting';

Should I be doing the following,

str = string.Format(str, "really", "doesn't");

or creating a method like so and calling str = str.ReplaceWithValues("really", "doesn't");

 public string ReplaceWithValues(this string str, params object[] values) {
    string ret = str;
    for (int i = 0; i < values.Length; i++) {
        ret = str.Replace(string.Concat("{", i, "}"), values.ToString());
    }
    return ret;
}

It seems like StringBuilder.AppendFormat() isn't efficient when it comes to doing simple replacements like this since it goes character by character through the string.

8
  • Do you need such a extreme performance tuning or you are just curious? Commented Sep 30, 2010 at 17:12
  • @Claudio Redi - I'm just curious. Commented Sep 30, 2010 at 17:13
  • "It seems like StringBuilder.AppendFormat() isn't efficient when it comes to doing simple replacements like this since it goes character by character through the string." What do you think string.Replace does? Commented Sep 30, 2010 at 17:21
  • 1
    Nitpicking: string str = '...' should use double quotes. Commented Sep 30, 2010 at 17:24
  • @Nelson: While you're at it - the method needs to be "static", since it's an extension method, too ;) Commented Sep 30, 2010 at 17:27

4 Answers 4

17

Why do you want to reinvent String.Format?

I'd just use the framework method - it does exactly what you want, is robust, and is going to make sense to those that follow...


Just to satisfy your curiousity:

It seems like StringBuilder.AppendFormat() isn't efficient when it comes to doing simple replacements like this since it goes character by character through the string.

String.Format, FYI, uses StringBuilder.AppendFormat internally. That being said, StringBuilder.AppendFormat is quite efficient. You mention that it goes "character by character" through the string - however, in your case, you're using multiple calls to Replace and Concat instead. A single pass through the string with a StringBuilder is likely to be much quicker. If you really need to know- you could profile this to check. On my machine, I get the following timings if I run both of the above 1,000,000 times:

String.Format -  1029464 ticks
Custom method -  2988568 ticks
Sign up to request clarification or add additional context in comments.

3 Comments

I'm just curious. Not anything that is planning to go into development.
@Jeremy: I just edited my answer to help your curiosity - as you can see, the framework method is better on just about every count. ;)
Just did 100 iterations of 10k of each, and my custom method is 1/2 the speed. Which is weird after looking at StringBuilder.AppendFormat()'s code.
2

The custom procedure will increase its cost with each additional placeholder and produce throwaway strings for the garbage collector with each intermediate call to Replace.

Besides the likelihood that string.Format is much faster than multiple calls to Replace, string.Format includes overloads to culture-sensitive operations as well.

The flexibility and intuitiveness of string.Format is at least as compelling as the speed.

Comments

1

If all you want is to concatenate some strings, why not just do that?

string result = "my " + x + " long string " + y + " need formatting";

or

string result = string.Concat("my ", x, " long string ", y, " need formatting");

3 Comments

Same reason anyone uses string.Format... it is cleaner looking than a bunch of concats.
+1 This is the fastest solution - string.Concat uses unmanaged methods internally to create an new string.
In your example it's not too bad, but it gets hairy with some more complex strings: "[{0}] {1}: {2}." becomes "[", x, "] ", y, ": ", z, ".". Or with quotes: "attr1=\"{0}\" attr2=\"{1}\"" becomes "attr1=\"", x, "\" attr2=\"", y, "\"". Which is clearer? Then you can add formatting like {0:C} which also simplifies it further.
0

In C# the + operator actually turns in to a string.Concat(), and I always thought String.Format("Hello: {0} {1}", "Bob", "Jones") was the fastest. It turns out, after firing up a sample ran outside the debugger, in release mode, that "Bob" + "Jones" is much faster. There is a cutoff point though. I believe around 8 concatenations or so, string.Format becomes faster.

1 Comment

I think that's because "Bob" + "Jones" will be optimized to "BobJones" in compile time in Release mode

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.