Which way to create strings is more run time efficient in C#
Number 1:
bool value = true;
int channel = 1;
String s = String.Format(":Channel{0}:Display {1}", channel, value ? "ON" : "OFF");
Number 2:
bool value = true;
String channel = "1";
string s = ":Channel" + channel + ":Display " + value ? "ON" : "OFF";
I'm going to add an example now to illustrate how the compiler treats the two, because there seems to be a lot of confusion in some of the other answers (edit: note that much of these confusions have now been deleted/edited away):
bool value = true;
int channel = 1;
String s = String.Format(":Channel{0}:Display {1}", channel,
value ? "ON" : "OFF");
The last line is compiled as:
String s = String.Format(":Channel{0}:Display {1}",
new object[2] {(object)channel, value ? "ON" : "OFF")};
note interestingly the creation of an array and a "box" for int channel, and of course the extra parsing required to find {0} / {1}.
Now Number 2:
bool value = true;
String channel = "1";
string s = ":Channel" + channel + ":Display " + (value ? "ON" : "OFF");
The last line is compiled as:
string s = string.Concat(":Channel", channel, ":Display ", value ? "ON" : "OFF");
here there is no array, no box (channel is now a string), and no parsing. The overload is public static string string.Concat(string,string,string,string); string.Concat is implemented very efficiently, pre-allocating a right-sized string in advance then over-writing, etc.
In most code, either is fine. The second version is technically more efficient (no box, no array, no parsing), but is a major pain if you ever want to internationalize later. In most applications you will not notice any difference between the two. The parsing is fast, and the box / array are collected cheaply as gen-zero objects. But cheap is not free.
This could help you to test this yourself. This was executed using .net v4.0.30319 runtime.
sw = new System.Diagnostics.Stopwatch();
// Number 1
bool value = true;
int channel = 1;
sw.Start();
for (int i = 0; i <= 100000; i++)
{
String s = String.Format(":Channel{0}:Display {1}", channel, value ? "ON" : "OFF");
}
sw.Stop();
sw.Reset();
// Number 2
sw.Start();
for (int i = 0; i <= 100000; i++)
{
string s = "Channel" + channel + ":Display " + (value ? "ON" : "OFF");
}
sw.Stop();
My result is:
Number 1: 136ms
Number 2: 91ms
So the second option has better performance. The fact that the first option uses an extra method call (string.Format()) and replacing parameters (as Marc remarked) is what makes the difference.
If instead of using 100.000 iterations I use 1.000.000, this is what I get
Number 1: 1308ms
Number 2: 923ms
Basically, same conclusion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With