views:

132

answers:

4
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  A: 

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
Reed Copsey
I'm just curious. Not anything that is planning to go into development.
Jeremy
@Jeremy: I just edited my answer to help your curiosity - as you can see, the framework method is better on just about every count. ;)
Reed Copsey
@Reed - 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.
Jeremy
@Jeremy: Make sure to run outside of VS's hosting process, in release, too...
Reed Copsey
+1  A: 

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");
dtb
Same reason anyone uses string.Format... it is cleaner looking than a bunch of concats.
Jeremy
+1 This is the fastest solution - `string.Concat` uses unmanaged methods internally to create an new string.
Callum Rogers
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.
Nelson
+2  A: 

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.

kbrimington
+1 for culture-sensitive
Platinum Azure
A: 

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.

Andy K