1

A colleague told me that using the following method:

 string url = "SomeURL";
 string ext = "SomeExt";
 string sub = "SomeSub";
 string subSub = "moreSub";
 string Url = @"http://www." + Url +@"/"+ ext +@"/"+  sub  + subSub;

is not efficenet (takes more resources) and it is preferred to use the following method:

 string Url = @"http://www.#URL.#EXT/#sub/#subSub";
 string url = "SomeURL";
 string ext = "SomeExt";
 string sub = "SomeSub";
 string subSub = "moreSub";
 Url = Url.Replace("#URL",url)
 Url = Url.Replace("#EXT",ext);
 Url = Url.Replace("#sub",sub);
 Url = Url.Replace("#subSub",subSub);

Is that true? and what is the explanation behind it?

I read this Answer and it got me wondering what about this case :

 string Url = @"http://www.#URL.#EXT/#sub/#subSub";
 string url = "SomeURL";
 string ext = "SomeExt";
 string sub = "SomeSub";
 string subSub = "moreSub";
string finalUrl = new StringBuilder(Url )
        .Replace("#URL", "URL")
        .Replace("#EXT", "EXT")
        .Replace("#sub", "sub")
        .Replace("#subSub", "subSub")
        .ToString();

is that more efficenet then ??

0

7 Answers 7

8

Your colleague is completely wrong.

He is mis-applying the fact that strings are immutable, and that appending two strings will create a third string object.
Your method (a + b + c) is the most efficient way to do this.
The compiler transforms your code into a call to String.Concat(string[]), which uses unsafe code to allocate a single buffer for all of the strings and copy them into the buffer.

His advice should be to use a StringBuilder when concatenating strings in a loop.

EDIT: String.Concat (which is equivalent to + concatenation, like your first example) is the fastest way to do this. Using a StringBuilder like in your edit will be slower, because it will need to resize the string during each Replace call.

Sign up to request clarification or add additional context in comments.

2 Comments

-1 because its not the most effecient way to do this .. using stringbuilder is more effecient
@peacmaker WRONG! If you don't have a loop, a StringBuilder is slower. Calling Concat (+) will allocate a single string of the correct size; a StringBuilder will need to re-allocate. Please do not downvote without knowing what you're talking about.
8

It is not true, you can't see it because the code is wrong. It should be:

Url = Url.Replace("#URL", url);
Url = Url.Replace("... etc");

You can usually make string concatenation more efficient by using StringBuilder. However, that can only do a better job with so few strings if you can accurately guess the Capacity you need. Your specific code however gets optimized by the compiler to an overload of String.Concat() that takes multiple strings. Which uses an internal high-speed concatenator, impossible to beat with StringBuilder.

Take advantage from the composite formatting feature available in String.Format:

string Url = string.Format(@"http://www.{0}/{1}/{2}{3}", url, ext, sub, subSub);

Quick and readable.

1 Comment

Using StringBuilder wouldn't make the concatenation more efficient. It's a single expression - the compiler will make a single call to String.Concat.
5

Firstly, I'm almost certain that replace is not more efficient than concatenation. If anything, it is probably even less efficient.

Secondly, your code with replace actually will not work as you expect. The Replace method does not change string. (string cannot be changed, by the way; ever) Instead, the Replace method returns a new string. And the old one stays the same. Therefore, in order for it to work, you should write:

Url = Url.Replace("#URL",url)
Url = Url.Replace("#EXT",ext);
Url = Url.Replace("#sub",sub);
Url = Url.Replace("#subSub",subSub);

Preferred method for things like this is using string.Format:

Url = string.Format( "http://www.{0}.{1}/{2}/{3}", url, ext, sub, subSub );

However, on small cases like yours (less than 10 concatenations, I would say), it is actually most efficient to use concatenation.

And lastly, if you have many concatenations (dozens), you should use StringBuilder.

1 Comment

Alternatively Url = Url.Replace("#URL",url).Replace("#EXT",ext).Replace("#sub",sub).Replace("#subSub",subSub); but agreed that string.Format should be the preferred method.
4

Your colleague is incorrect. The Replace() method (or any method which 'modifies' strings) creates a new string each time it is called. So calling it four times creates three more strings than you need to generate the output. Your first method creates only the one output string (not counting the strings which make up the components of the url).

8 Comments

@Fyodor: You are wrong. str1 + str2 + str3 is transformed by the compiler into a single call to String.Concat
There are seven strings being concatenated in this example. This will result in three string.Concat calls.
@Fyodor: You're still wrong. This will compile to a single call to String.Concat with seven arguments.
There is no version of Concat with seven arguments. Only up to 4. And if you mean the one with params String[], then it would involve creating an array.
@SLaks: No, it will actually create an array and call String.Concat(string[]) (try it) - but it's still just a single call.
|
4

For only five strings, it doesn't really matter performance-wise. Use simple concatenation, string.Format(), Url.Replace(), whatever best displays the intent of what you are doing. This is far more important than micro-optimisations that are unlikely to work.

Remember that if you are concatenating many strings, it would be a good idea to use the StringBuilder class because otherwise large numbers of strings would be created and performance would be affected.

I would personally use string.Format in your case (more concise, all on one line, shows intent):

string Url = string.Format("http://www.{0}/{1}/{2}{3}", url, ext, sub, subSub);

Comments

1

Others have pointed out that your colleague is blowing smoke. I'd like to explain why he appears to be confused (but not exactly 100% wrong):

This code is efficient:

string url = "SomeURL";
string ext = "SomeExt";
string sub = "SomeSub";
string subSub = "moreSub";
string Url = @"http://www." + Url +@"/"+ ext +@"/"+  sub  + subSub;

It's efficient because there is only one concatenation happening (of multiple strings).

On the other hand, if you wrote it the following way, it would be very inefficient:

// BAD CODE!  Don't write this.
string url = "http://www.";
url += "SomeURL";
url += "/";
url += "SomeExt";
url += "/";
url += "SomeSub";
url += "moreSub";

The above code has to allocate a new string for every concatenation. If you do this on a few lines of code, it's not horrible, just bad. If you do it inside a tight loop, it's a performance killer.

If you compare the second version of the code to a version using string.Format:

string url = string.Format("http://www.{0}/{1}/{2}{3}",
    "SomeURL", "SomeExt", "SomeSub", "moreSub");

Then in this case, the string.Format (not string.Replace) version will be much faster, because it only has to construct one string.

So the answer as to whether or not string.Format is more efficient than concatenation depends on how you do the concatenation and how you do the format. A single concatenation (which can concatenate multiple strings, as I explained earlier) is far faster than a Format. But a series of sequential concatenations will be slower than a single Format.

In other words, concatenation is slower than Format (not Replace) if you mess the former up horribly.

2 Comments

I suspect that the compiler would optimize your second example to be equivalent to the first. (At least in Release mode)
@SLaks: That may be true if you use that code verbatim, but definitely won't be true in a loop, and is very unlikely to be true if any other statements happen between the concatenations. And even if the optimizer does manage to work this out, it's still a horrible practice to rely on such optimizations.
-2

because when you use "+" you are creating a new object so its not efficenet

1 Comment

You are wrong. str1 + str2 + str3 is transformed by the compiler into a single call to String.Concat

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.