开发者

Does a string concatenation allocate new strings in memory for each string in the chain or only for the string being changed?

//will need these in a 开发者_如何学Gosecond
string a = "5";
string b = "7";
string c = "3";

So because C# will allocate more strings in memory

string mystring = "";
mystring += a;
mystring += b;
mystring += c;

is going to be slower than

StringBuilder sb = new StringBuilder();
sb.Append(a).Append(b).Append(c);

So then, what about:

string mystring = "";
mystring += a + b + c;

Is it just the += part that is slow, or is + also a culprit here?


This line:

mystring += "5" + "7" + "3";

will actually compile into the same as:

mystring = String.Concat(mystring, "573");

When you concatenate literal strings, the compiler will do that for you at compile time.

If you use string variables instead:

string mystring = "";
string str1 = "5";
string str2 = "7";
string str3 = "3";
mystring += str1 + str2 + str3;

The last line will compile into the same as:

mystring = String.Concat(myString, str1, str2, str3);

As you send all the strings into the Concat method, it can create the resulting string in one go. What it does is quite similar to using StringBuilder to create the string.


The following will make 3 memory allocations and copy the data multiple times:

string mystring = "";
mystring += a; // allocate string; copy a
mystring += b; // allocate string; copy a and b
mystring += c; // allocate string; copy a, b, and c

This will probably make 2 memory allocations and copy the data twice:

StringBuilder sb = new StringBuilder(); // make 1 allocation for all the strings
sb.Append(a).Append(b).Append(c); // copy a, b, and c
string mystring = sb.ToString();  // make another allocation; copy a, b, and c

This will make just 1 memory allocation and only copy each string once because the compiler optimizes consecutive string concatenations into a single call to String.Concat:

string mystring = "";
mystring += a + b + c; // allocate one string; copy a, b, and c


+= is sintax sugare for s +a.

What about performance, on big numbers of strings StringBuilder is much much more performant.


Well I think your example would be better with variables. The compiler will actually do this concatenation for you since these are two string literals. So in this example there will actually do all of the work and there will be no performance hit.

To give you a better answer, there is no benefit to putting them on the same line like that. The compiler will treat them the same way and do an equal number of new string creations whether each concatenation is its own line or whether they're chained.


In the first case you can assume the compiler or the JIT to do the appending and only allocate one string. If the constant strings are replaced with variables that are not known at compile time the StringBuilder should be faster because it does not allocate that many strings.

On the other hand, three strings with length = 1 does not need much allocation and might be faster than instantiating a StringBuilder anyway. Only the one who measure carefully will know for sure.


There is no difference. A string concatenation is a string concatenation I believe. If you are only doing a couple of concatenations (3 or 4), it's probably better to not use StringBuilder cause StringBuilder has overhead that can be slower than the concatenations.

UPDATE

Here is the test I wrote to verify this:

    [Test]
    public void TestString() {
        IList<string> strings = new List<string>();
        Stopwatch watch = new Stopwatch();
        watch.Start();
        for (int index = 0; index < 100000; index++) {
            string t = "1" + "2" + "3";
            // Keep the compiler from optimizing this away
            strings.Add(t);
        }
        watch.Stop();
        Console.WriteLine("string: " + watch.ElapsedMilliseconds);
        watch.Reset();
        watch.Start();
        for (int index = 0; index < 100000; index++) {
            StringBuilder b = new StringBuilder();
            b.Append("1").Append("2").Append("3");
            strings.Add(b.ToString());
        }
        watch.Stop();
        Console.WriteLine("StringBuilder: " + watch.ElapsedMilliseconds);
    }

producing this output:

string: 1
StringBuilder: 25
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜