Performance: string "concatenated" or all in the same line?

Asked

Viewed 2,226 times

13

I have a loop with thousands of results that renders a table. The string is mounted through Stringbuilder in this way (sample snippet):

ScriptTbody.AppendLine("</select>");
ScriptTbody.AppendLine("<p class=\"valAnoInicio\"></p>");
ScriptTbody.AppendLine("</td>");
ScriptTbody.AppendLine("<td>");
ScriptTbody.AppendLine("<select class=\"cbPeriodoIniEdit\">");
ScriptTbody.AppendLine("</select>");
ScriptTbody.AppendLine("<p class=\"valPeriodoInicio\"></p>");
ScriptTbody.AppendLine("</td>");

There may be some performance improvement if I put the whole code in one line, as follows:?

ScriptTbody.AppendLine("</select><p class=\"valAnoInicio\"></p></td><td><select class=\"cbPeriodoIniEdit\"></select><p class=\"valPeriodoInicio\"></p></td>");

And if it was a concatenation, as for example the following code?

comand.CommandText  = "SELECT ";
comand.CommandText += "    TI.COD_INDICADOR, ";
comand.CommandText += "    TI.TXT_DESCRICAO, ";
comand.CommandText += "    TI.COD_PRODUTO, ";
comand.CommandText += "FROM ";
comand.CommandText += "    TB_INDICADOR TI";

More advanced explanations about how language works are welcome.

3 answers

11


The best is always to keep in a String that is unique at compile time than at runtime.

And, believe it or not, in C# it is possible to use line breaks in a single String using the character @ (arroba) at the beginning of it.

string query =
  @"SELECT 
        TI.COD_INDICADOR,
        TI.TXT_DESCRICAO,
        TI.COD_PRODUTO, 
    FROM 
        TB_INDICADOR TI";

Moreover, second this topic in the OS, if you concatenate String literals into the same command, they will be concatenated at compile time, then it would give the same effect on runtime performance something like:

comand.CommandText  = 
    "SELECT " +
    "    TI.COD_INDICADOR, " +
    "    TI.TXT_DESCRICAO, " +
    "    TI.COD_PRODUTO, " +
    "FROM " +
    "    TB_INDICADOR TI";

Use StringBuilder to concatenate String literals will decrease the program’s performance as it will prevent the compiler from optimizing literals.

On the other hand, if the compiler cannot know the size of the String at compile time, for example if we concatenate variables, the StringBuilder is usually faster than concatenating the values directly. I say "generally" because I really don’t know how much the compiler or CPU would be able to optimize certain exceptional cases.

  • 1

    Through the mentioned topic I got to this link (http://yoda.arachsys.com/csharp/stringbuilder.html) with great explanations, as well as you summarized in the answer. The @ solution is very good because I can easily manipulate the code in the BD program and then paste it into the application.

5

In case of replacing multiple calls from StringBuilder.Append for only one, the gain will be minimal.

On one occasion, working with the class StringBuilder I noticed a great improvement in performance when initializing the StringBuilder large enough to store the entire result. I did this using two routines, one to count the required size, and one to mount the string.

To initialize Stringbuilder with a size just pass an integer number in the constructor:

int tamanho = CalculaEspacoNecessario();
var sb = new StringBuilder(tamanho);
PreencherStringBuilder(sb);
  • +1 Great tip. Initialize the initial ability of objects with buffer internal (Stringbuilder, List), when you have an idea of size, can greatly improve performance.

  • 2

    Of course it only works if CalcularEspacoNecessario() is faster than the crescimetnos of StringBuilder.

3

It has already been properly said that the best way is to use a single string in the case presented. It is quick and readable.

But if there is a reason to do the sequential concatenation, it can be used without performance problems. It ends up becoming a single string at compile time. The only problem is being less readable.

There is compiler optimization in many cases. But not at all. If all sizes stringthe involved ones are not known, there is not so much optimization. In these cases the optimization only transforms the concatenations in the method concat(). It is certainly better because it avoids unnecessary allocations, but size calculation is still required.

Despite the property SqlCommand.CommandText be the type string, I have doubts if it can be so optimized.

If a StringBuilder may be suitable and have no performance impairment. It may even be faster than a method concat() of string. When you know the total size required for all strings simply, possibly as constant literal, the StringBuilder is very fast. Internally (.NET Core) the concat() uses a StringBuilder optimized, therefore find that the first is faster than the second does not make sense. Of course in cases that have only 4 strings the concatenation is made in a simpler way without StringBuilder.

But so far little new has been added to what has already been said in the other answers.

Alternative: Resources

There are cases that to facilitate the work, the text should not be in the code. It should be in an external file, when relevant, or be in Resources. It can be easier to maintain this and is very fast in the second case.

For everything there is the best applied solution. This is a case that facilitated maintenance can be more important than performance. In case you take the Resource performance will not be affected much. And even if it is, it will not create a problem for the application. This concern with performance makes sense for cases of extreme manipulations of strings. In the case of file access the performance will obviously be affected by access to mass memory. But it will still not affect the application. Of course this solution should only be chosen when you want to have the possibility to change the text easily after the compilation, when you want to give this freedom to the user.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.