What is the most appropriate way to concatenate strings?

30

There are different methods for concatenating strings, such as

  • Concatenating with the "abc" + str
  • Formatting String.Format("abc{0}", str);
  • Using StringBuilder new StringBuilder("abc").Append(str);
  • Using the Concat method of String String.Concat("abc", str);

In what situation should I use each one? What can be more efficient in each case?

    
asked by BrunoLM 11.12.2013 в 21:42

4 answers

35

First of all, what is literal constant ?

A literal constant is the representation of a value of a string in the source code, eg

"isto é uma constante literal"

Another example:

var str = "foo";

In this example str is a string and "foo"

In our day-to-day life we do not need to point out this difference, but when we talk about performance over strings it is crucial to differentiate. Because literal constants are values that are present directly in the source code this gives the compiler the opportunity to optimize these operations (such as concatenation at compile time).

Operator +

"A temperatura em " + cidade + " é de " + temperatura;

Pro :

  • If you concatenate literal constants the concatenation is performed at compile time.
  • It is considered the default.

Contra :

  • Unreadable; difficult editing.

string.Concat

string.Concat("A temperatura em ", cidade, " é de ", temperatura);

In terms of performance it is identical to the operator + (except in case of literal constants).

string.Format

string.Format("A temperatura em {0} é de {1}", cidade, temperatura);

Pro :

  • Preferred by many when formatting concatenation (more readable).
  • Easy to use a concatenated string multiple times in the original string (just repeat the index).

Contra :

  • Little performanceist .
  • An execution (not build) error is generated if an invalid number of parameters to be concatenated is passed.
  • In a string with many concatenations, it may not be very friendly to have to keep concatenation index numbers.

StringBuilder

new StringBuilder("A temperatura em ").Append(cidade).Append(" é de ").Append(temperatura);

StringBuilder is a class specific to string construction. The big difference from the previous methods is that while the traditional System.String is an immutable object, that is, every operation creates a new string, since StringBuilder is changeable, making it the most pervasive in scenarios involving many operations (read concatenations in loops).

It is important to note that the use in the above example is a case where StringBuilder should not be used.

Considerations

We as programmers like this kind of subject a lot but the reality is that worrying about performance in trivial string concatenations is called micro optimization (notice the bad connotation).

As a general rule, I particularly follow:

  • I try to use simple concatenation, via operator + .
  • If by chance the project I'm working on assumes another way, string.Concat for example, I use it. Consistency is important.
  • When a large number of concatenations of literal constants is done by the + operator. This concatenation will be done at compile time saving precious render cycles.
  • When the strings involved are large, multiple operations, loop operations, so when heavy work is done on strings use StringBuilder. Do not use it for trivial work.
11.12.2013 / 23:28
9

Since every string can be considered an Array of characters, concatenating strings in the classic way is very costly. For every% wc% used, a copy of a new string is generated in memory. In the case of C #, as explained below, concatenations using + are translated to + .

The best way is to use the String.Concat() class together with the StringBuilder method. Here's how to implement a StringBuilder class to understand how it improves concatenation performance: link

When to use: Concatenations within loops, when the number of concatenations is not predicted.

The Append is only suitable for replacing placeholders, such as: String.Format() . By design, this path is not recommended for concatenation because it makes use of Replaces, which is very costly for that purpose.

The String.Format("Olá {0}, você tem {1} mensagens.", "Beto", 23); has a performance equal to concatenate with a + sign, since it only encapsulates the String.Concat() operand so to speak.

For the following code:

string a = "Um";
string b = "dois";
string c = "Tres";
string d = a + b + c;

It will be interpreted in the compiler as:

string a = "Um";
string b = "dois";
string c = "Tres";
string d = String.Concat(a, b, c);

When to use: If you need to combine two arrays or lists into one variable. You can extend this method to other types of inputs.

If you'd like to explore the details of string concatenation, there's a detailed article on this .

    
11.12.2013 в 21:45
6

In doubt, test ...

Times obtained with the code below (it's a tosko benchmark and varies according to the number of iterations, but you can get an idea):

Testing TestSum ... 37.076 ms

TestingContest ... 36.346 ms

Testing TestarStringBuilder ... 3 ms

TestingStream Testing ... 10 ms

using System;
using System.Diagnostics;
using System.IO;
using System.Text;

namespace ConsoleApplication1
{

    public class Program
    {

        private const int LOOP_COUNT = 100000;

        public static void Main(string[] args)
        {
            Testar(TestarSoma);
            Testar(TestarConcat);
            Testar(TestarStringBuilder);
            Testar(TestarStream);
        }

        private static void Testar(Func<string> metodo)
        {
            var sw = new Stopwatch();

            Console.Write("Testando {0}... ", metodo.Method.Name);
            sw.Start();
            metodo();
            sw.Stop();
            Console.WriteLine("{0:N0} ms", sw.ElapsedMilliseconds);
        }

        private static string TestarSoma()
        {
            var a = "Um";
            var b = "Dois";
            var c = "Três";
            var d = "";

            for (var ct = 0; ct <= LOOP_COUNT; ct++)
            {
                d += a + b + c;
            }

            return d;
        }

        private static string TestarConcat()
        {
            var a = "Um";
            var b = "Dois";
            var c = "Três";
            var d = "";

            for (var ct = 0; ct <= LOOP_COUNT; ct++)
            {
                d = string.Concat(d, a, b, c);
            }

            return d;
        }

        private static string TestarStringBuilder()
        {
            var a = "Um";
            var b = "Dois";
            var c = "Três";
            var d = new StringBuilder();

            for (var ct = 0; ct <= LOOP_COUNT; ct++)
            {
                d.Append(a);
                d.Append(b);
                d.Append(c);
            }

            return d.ToString();
        }

        private static string TestarStream()
        {
            var a = "Um";
            var b = "Dois";
            var c = "Três";

            using (var ms = new MemoryStream())
            using (var sw = new StreamWriter(ms))
            {
                for (var ct = 0; ct <= LOOP_COUNT; ct++)
                {
                    sw.Write(a);
                    sw.Write(b);
                    sw.Write(c);
                }

                sw.Flush();
                ms.Seek(0, SeekOrigin.Begin);

                using (var sr = new StreamReader(ms))
                {
                    return sr.ReadToEnd();
                }
            }
        }

    }
}
    
05.02.2014 в 22:33
1

No doubt, use concat() or join() to join small string pieces.

To concatenate something like multiple big phrases / lines (no matter whether inside or outside of loop) consider using StringBuilder .

Only use + if you concatenate LYRICS or a few WORDS.

See this page , test WITH YOUR string and take your conclusion.

    
09.06.2016 в 21:18