Why the speed rank is: AddStringInMutipleStatement
> AddStringInOneStatement
> AddStringInMutipleStatementEx
?
Is it related the temp string object created on runtime? What the detail is?
namespace Test
{
class Program
{
static string AddStringInOneStatement(int a, string b, int c, string d)
{
string str;
str = "a = " + a.ToString() + "b = " + b + "c = " + c.ToString() + "d = " + d;
return str;
}
static string AddStringInMutipleStatement(int a, string b, int c, string d)
{
string str = "";
str += "a = " + a.ToString();
str += "b = " + b;
str += "c = " + c.ToString();
str += "d = " + d;
return str;
}
static string AddStringInMutipleStatementEx(int a, string b, int c, string d)
{
string str = "";
str += "a = ";
str += a.ToString();
str += "b = ";
str += b;
str += "c = ";
str += c.ToString();
str += "d = ";
str += d;
return str;
}
static void Main(string[] args)
{
uint times = 10000000;
Stopwatch timer = new Stopwatch();
timer.Start();
for (int i = 0; i < times; i++)
{
AddStringInOneStatement(1, "2", 3, "4");
}
timer.Stop();
Console.WriteLine("First: " + timer.ElapsedMilliseconds); // 4341 ms
timer.Reset();
timer.Start();
for (int i = 0; i < times; i++)
{
AddStringInMutipleStatement(1, "2", 3, "4");
}
timer.Stop();
Console.WriteLine("Second: " + timer.ElapsedMilliseconds); // 3427 ms
timer.Reset();
timer.Start();
for (int i = 0; i < times; i++)
{
AddStringInMutipleStatementEx(1, "2", 3, "4");
}
timer.Stop();
Console.WriteLine("Second: " + timer.ElapsedMilliseconds); // 5701 ms
}
}
}
Firstly, a few points on your benchmarking:
GC.Collect()
after each test, so that garbage created by one test doesn't affect anotherThere are various costs here:
In the first method, the compiler is actually transforming your code into:
string[] bits = new string[] { "a = ", a.ToString(),
"b = ", b,
"c = ", c.ToString(),
"d = ", d };
return string.Concat(bits);
The second and third methods create several intermediate strings; it looks like they create roughly the same number of intermediates (because each line in the second method creates two) but the third method requires more copying - the intermediate strings all contain "the whole of the string so far" whereas half of the intermediate strings in the second method are just short ("b = " + b
etc). That may be responsible for the difference.
I suspect in this case the cost of the array creation (and population) in the first method outweighs the cost of the intermediate strings in the second method. Indeed, changing the first method to just create and population the array, that appears to take up more than half of the running time (on my machine). That creation/population includes the int.ToString()
calls as well, mind you... which seem to be a large part of the expense too.
I've removed the int.ToString()
part in a local copy of your benchmark, and the result still holds - but is even clearer as there's less constant overhead.
See more on this question at Stackoverflow