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开发者_StackOverflow社区")
.Replace("#EXT", "EXT")
.Replace("#sub", "sub")
.Replace("#subSub", "subSub")
.ToString();
is that more efficenet then ??
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.
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.
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
.
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).
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);
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.
because when you use "+" you are creating a new object so its not efficenet
精彩评论