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