So I am primarily a C# and Java developer but I suppose this question could pertain to any programming languages that uses StringBuilder or some derivative thereof.
Okay so it is more or less common knowledge that concatenate even a small number of strings can be a major performance killer (although even that is debatable). My question is does anyone have knowledge of the performance effects of using a string builder within a string builder. To clarify what I mean by that let me include some dummy code that should help illustrate my point.
Also I realize that there is naturally a performance hit by calling multiple instances of StringBuilder but I do not believe that I would be calling it enough to cause any real performance issues. (This assumption may also be wrong any opinion on that would be helpful as well)
public string StringToGet()
{
StringBuilder sb = new StringBuilder("Some Text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append(MethodThatCreatesAnotherString());
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append(MethodThatCreatesAnotherString());
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append(MethodThatCreatesAnotherString());
//etc
return sb.toString();
}
private string MethodThatCreatesAnotherString()
{
StringBuilder sb = new StringBuilder("Other text");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
return sb.ToString();
}
Logic tells me that this shouldn't be a problem, but something about this approach just does not seem to look right to me. Can anyone shed some light on the following questions
Any onsite on this would be greatly appreciated.
String is immutable whereas StringBuffer and StringBuilder are mutable classes. StringBuffer is thread-safe and synchronized whereas StringBuilder is not. That's why StringBuilder is faster than StringBuffer. String concatenation operator (+) internally uses StringBuffer or StringBuilder class.
StringBuilder class can be used when you want to modify a string without creating a new object. For example, using the StringBuilder class can boost performance when concatenating many strings together in a loop.
We can approach comparing String and StringBuilder by creating an instance of the String and StringBuilder classes. We will perform concatenation of String instances with the += operator and concatenation of StringBuilder instances with the . append() method.
Typically, if the number of straight-up string concatenations are more than 5, it's better to use StringBuilder
. If you have control over the methods that in turn build a string, why not consider passing your StringBuilder
into the method?
public void MethodThatCreatesAnotherString(StringBuilder sb)
{
// code that appends to StringBuilder
}
So, when it's time to call that function, you pass in your current StringBuilder, and you don't lose a performance hit, but it's at the expense of potential obfuscation.
That said, unless you're getting into the hundreds or thousands of these operations, I wouldn't worry about premature optimization here. Your main performance hit is having to do it twice (i.e. append the strings inside the method, and then appending the complete string), but you still won't be taking the performance hit to the extent of using +
concatenation.
Edit: A clarifying example of how to use it:
string SomeMethodCreatingAString()
{
StringBuilder sb = new StringBuilder();
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
sb.append("more text to add");
MethodThatCreatesAnotherString(sb);
// more text
return sb.ToString();
}
So, you don't ever append that string from the second method, you simply use the same StringBuilder
within that method. Hopefully that makes sense.
I am not sure about the performance implications but changing the signature of your MethodThatCreatesAnotherString
method to accept a StringBuilder
would remove the need for multiple instances of StringBuilder
.
As http://www.codinghorror.com/blog/2009/01/the-sad-tragedy-of-micro-optimization-theater.html shows the difference between different ways of concatenating strings is really pretty minor until you get to really large numbers of concatenations.
Therefore, unless you already know you have a performance problem with this code then I think its fine. Your really only getting 3 extra string builder inits and 3 extra string allocations in your example.
In the long run you should just try to do what is simplest and only worry about complicated micro optimizations if you are sure you need them and testing bares them out.
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