You need to append strings
together, yielding a longer string, using the C# programming language. Measure
performance and avoid string append methods that can cause severe performance
problems. Here we see how you can start using StringBuilder by including the System.Text namespace in your file. You usually
use StringBuilder in a loop, and the examples here show more usages.
String:
Has immutable buffers; cannot be changed; each operation returns a new string;
copies can increase memory pressure.
StringBuilder:
Has mutable buffers; can be changed without copying; usually used in loops.
Use StringBuilder
First, we see some of the
essential methods on the StringBuilder type in the base class library. The
methods shown here will allow you to use it effectively in many programs,
appending strings and lines. This example does not show a loop, and it is not
ideal as a program, but it is for demonstration purposes.
Program that uses StringBuilder [C#]
using System;
using System.Text;
using System.Diagnostics;
class Program
{
static void Main()
{
// 1.
// Declare a new
StringBuilder.
StringBuilder builder
= new StringBuilder();
// 2.
builder.Append("The
list starts here:");
// 3.
builder.AppendLine();
// 4.
builder.Append("1
cat").AppendLine();
// 5.
// Get a reference to
the StringBuilder's buffer content.
string innerString =
builder.ToString();
// Display with Debug.
Debug.WriteLine(innerString);
}
}
Output
The list starts here:
1 cat
Description of the new
keyword. It uses
the 'new' keyword for StringBuilder. Use the new keyword to make your
StringBuilder. This is different from regular strings. StringBuilder has many
overloaded constructors.
Description of appending. It calls the instance Append() method. This method adds the
contents of its arguments to the buffer in the StringBuilder. Every argument to
StringBuilder will automatically have its ToString method called.
AppendLine method. It calls AppendLine, which does the exact same thing as Append(),
except with a newline on the end. Next, Append and AppendLine call themselves.
This shows terse syntax with StringBuilder. Finally, ToString returns the
buffer. You will almost always want ToString(). It will return the contents as
a string.
Memory pressure
StringBuilder will make
your appends go faster usually, but there's another benefit. In .NET, there is
a concept of "memory pressure", meaning that the more temporary
objects created by your app, the more often garbage collection runs.
StringBuilder creates fewer temporary objects and adds less memory pressure.
This site contains an experiment that shows the memory usage of a StringBuilder
after garbage collection occurs.
Replace and insert
Here we see how you can use
StringBuilder to replace or insert characters in loops. First convert the
string to a StringBuilder, and then call StringBuilder's methods to do these
operations. This is faster because the StringBuilder type uses character arrays
internally, not unchangeable strings.
Program that uses Replace [C#]
using System;
using System.Text;
class Program
{
static void Main()
{
StringBuilder builder
= new StringBuilder(
"This is an example string that is an
example.");
builder.Replace("an",
"the"); // Replaces 'an' with
'the'.
Console.WriteLine(builder.ToString());
Console.ReadLine();
}
}
Output
This is the example string that is the example.
When to avoid
When you don't have a loop,
generally you should avoid StringBuilder. There is lots of logic in
StringBuilder that will be slow on very small operations. StringBuilder can
make your code more cumbersome. Here we look at some potential problems with
using StringBuilder in problems.
When to consider char
arrays. Character
arrays, specified as char[], are vastly simpler, but your code must be more
precise. If you know a maximum or absolute size of your output string, and your
requirements are simple, use char arrays.
Consider this common
mistake. Many
developers make a very specific StringBuilder mistake that reduces speed by
about 40%. Don't use the + operator on strings within a StringBuilder. It will
simply draw in the slowness of strings, resulting in many temporary assignments
and copies to the managed heap.
What about AppendFormat? AppendFormat draws in regular strings and substitutions.
Internally, many versions of AppendFormat in the .NET Framework are implemented
with StringBuilder instances. It is usually faster to call Append repeatedly
with all the required parts. However, the syntax of AppendFormat can be clearer
to read and maintain in some programs.
Loops
Here we see how you can use
StringBuilder in a simple loop. As I have noted, almost always your
StringBuilder will be used in a loop. This can be a foreach, for, or while
loop. Here's another example of StringBuilder, but in a foreach loop.
Program that uses foreach [C#]
using System;
using System.Text;
class Program
{
static void Main()
{
string[] items = {
"Cat", "Dog", "Celebrity" };
StringBuilder builder2
= new StringBuilder(
"These items are
required:").AppendLine();
foreach (string item
in items)
{
builder2.Append(item).AppendLine();
}
Console.WriteLine(builder2.ToString());
Console.ReadLine();
}
}
Output
These items are required:
Cat
Dog
Celebrity
AppendFormat
The AppendFormat method on
the StringBuilder type is very important and deserves a closer look. It can be
used to add text to your StringBuilder based on a pattern. You can use
substitution markers to fill fields in this pattern. This site has more detail
about the AppendFormat method.
Benchmark
This site has a separate
article on benchmarks of StringBuilder versus string here. Further on in the
article you are reading, you can see a way of using StringBuilder more
effectively as a parameter. The key to good performance here is to avoid string
copies, thereby reducing allocations on the managed heap.
Equals
You will find that
StringBuilder defines an instance method Equals that can be used to compare the
capacities and contents of two StringBuilders. It is important to use this
method because you can avoid lots of error-prone code that you write yourself.
There are some subtleties to Equals, however, which are looked into on this
site.
Clear data
How can you clear the data
inside your StringBuilder that you have already appended? Sometimes it is best
to allocate a new StringBuilder instance; other times, you can assign the
Length property to zero or use the Clear method from the .NET Framework 4.0.
StringBuilder argument
Here we can see how you can
use the StringBuilder type as an argument. This is a significant optimization
because it will avoid converting back and forth to strings. The example shows
StringBuilder parameters and reusing the same StringBuilder. Strings alone
would be hugely slower in many cases.
Example with many StringBuilders created
[C#]
using System;
using System.Text;
class Program
{
static string[] _items =
new string[]
{
"cat",
"dog",
"giraffe"
};
/// <summary>
/// Append to a new
StringBuilder and return it as a string.
/// </summary>
static string A1()
{
StringBuilder b = new
StringBuilder();
foreach (string item
in _items)
{
b.AppendLine(item);
}
return b.ToString();
}
static void Main()
{
// Called in loop.
A1();
}
}
Example with one StringBuilder used as
parameter [C#]
using System;
using System.Text;
class Program
{
static string[] _items =
new string[]
{
"cat",
"dog",
"giraffe"
};
/// <summary>
/// Append to the
StringBuilder param, void method.
/// </summary>
static void
A2(StringBuilder b)
{
foreach (string item
in _items)
{
b.AppendLine(item);
}
}
static void Main()
{
// Called in loop.
StringBuilder b = new
StringBuilder();
A2(b);
}
}
Important differences
Version 1: Many StringBuilders created
Increased memory pressure
Version 2: One StringBuilder created
Less memory pressure
Same result as before
Benchmark results (many iterations of
methods)
Version 1: 5039 ms
Version 2: 3073 ms
Immutable strings
The word 'immutable'
indicates that the data being pointed at is not changeable. To see an example
of an immutable object in the C# language, try to assign to a character in a
string. This causes a compile-time error, because the string type does not define
a set accessor. However, character arrays can be changed. Internally,
StringBuilder uses "mutable" char arrays for its buffer.
ArgumentOutOfRangeException
You may be getting this
exception if you are putting too much data in your StringBuilder. The maximum
number of characters in a StringBuilder is equal to Int32.MaxValue. I suggest
you check for infinite loops or other serious problems.
Members
Here we look at more
members on the StringBuilder type in the .NET Framework base class library.
This document only shows some of the StringBuilder members. The Replace, Insert
and Remove methods are very important, even though they are less common than
Append.
Append
This is the most basic StringBuilder method. You can use Append with a format
string, a string, or other data types such as chars and integers. Nothing other
than the argument's string representation is appended.
AppendFormat
Appends string using the formatting syntax available in string.Format. This can
improve code clarity.
EnsureCapacity
This rarely is useful for changing the capacity. This is an optimization you
can use.
Insert
Very similar to the Replace method. Used to add characters at an index.
Remove
Essentially the same as the Remove method on string. Avoids character array
copying.
Replace
Replaces one string of characters with another. This has some performance
advantages over the Replace method on the string type.
ToString
Internally converts the buffer to a string type. Often does not perform any
additional allocations. Please see the ToString article on this website.
Summary
We saw ways you can
effectively use StringBuilder in your C# application. StringBuilder can improve
the performance of your program, even if you misuse it. However, by using it
optimally, results are much better. Use StringBuilder as a parameter instead of
calling ToString frequently. The article doesn't show many genuine secrets, but
the tips are valuable nonetheless.
Enjoy the day with Lots of smile and Happiness.....
No comments:
Post a Comment