Concatenated string performance

How to create strings for longer runtime 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"; 
+7
source share
4 answers

Now I'm going to add an example to illustrate how the compiler treats them, because there are many problems in some other answers (edit: note that most of these confusions are now deleted / edited):

 bool value = true; int channel = 1; String s = String.Format(":Channel{0}:Display {1}", channel, value ? "ON" : "OFF"); 

The last line compiles as:

 String s = String.Format(":Channel{0}:Display {1}", new object[2] {(object)channel, value ? "ON" : "OFF")}; 

pay attention to the creation of the array and the β€œbox” for the int channel , and, of course, the additional parsing needed to search for {0} / {1} .

Now number 2:

 bool value = true; String channel = "1"; string s = ":Channel" + channel + ":Display " + (value ? "ON" : "OFF"); 

The last line compiles as:

 string s = string.Concat(":Channel", channel, ":Display ", value ? "ON" : "OFF"); 

there is no array, no field ( channel now a string) and no parsing. Overload public static string string.Concat(string,string,string,string) ; string.Concat runs very efficiently by first assigning a size string to the right and then rewriting, etc.

In most codecs, everything is fine. The second version is technically more efficient (no box, no array, no parsing), but it's a big pain if you ever want to internationalize later. In most applications, you will not notice the differences between them. Parsing is fast, and the block / array is cheaply collected as objects with zero zero. But cheap is not free.

+7
source

This can help you test it yourself. This was accomplished using .net v4.0.30319.

 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:

Number 1: 136 ms

Number 2: 91 ms

Thus, the second option has better performance. The fact that the first option uses an extra method call ( string.Format() ) and a parameter change (as Mark noted) is what makes the difference.

If instead of 100,000 iterations I use 1,000,000, this is what I get

Number 1: 1308 ms

Number 2: 923 ms

In principle, the same conclusion.

+6
source

Regarding Mark Gravell's answer: you can avoid boxing operations by passing channel.ToString (). I confidently confirmed that this gives a slight performance improvement for # 1 and # 2.

  • In case No. 1, you avoid boxing operations.
  • In case # 2, you avoid calling the implicit conversion operator.

But after trying to refute your theory (with longer concatenations and random strings) I have to admit that # 2 is faster than # 1.

0
source

Number 1 is the most effective.

The String.Format () function uses the System.Text.StringBuilder type internally to concatenate strings.

StringBuilder is used to represent mutable (so-called editable) strings, and it is the most efficient way to concatenate strings. http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx .

-4
source

All Articles