html += "size=\"200\"";
...actually creates a new variable called html and allows the old value to be garbage collected. So the old value of html has to be copied to a new location so that it can be appended to. The question in my mind is, how big does the string have to be, for this to start becoming slower than StringBuilder (or StringBuffer in Java)? The answer surprised me.
I'm reading Robert Morris' excellent book "Clean Code" on my Kindle and at location 7955 there is a code snippet.
I wondered if it really made sense to use a StringBuffer here. Surely the cost of the StringBuffer will exceed the cost of immutable strings. Here's some code that tries to answer that question. It runs two versions of this code each with different numbers of appends to see where the break even point is. Obviously it is a console project in C#.
using System;
using System.Text;
namespace StringBufferTest
{
class Program
{
static void Main(string[] args)
{
int Iterations = 1000;
Console.WriteLine(string.Format("All timings are for {0} iterations,", Iterations));
GetExecutionTimeSpan(RenderWithString, 1, 1); // Throw away
call because first call incurs overhead that we don't want reflected in our
results
GetExecutionTimeSpan(RenderWithStringBuilder, 1,1);
for (int
AttributeCount = 1; AttributeCount < 20; AttributeCount++)
{
Console.WriteLine(string.Format("String time
for {0} appends is {1}ms", AttributeCount,
GetExecutionTimeSpan(RenderWithString, Iterations,
AttributeCount).TotalMilliseconds));
Console.WriteLine(string.Format("StringBuilder time for {0} appends is {1}ms", AttributeCount, GetExecutionTimeSpan(RenderWithStringBuilder,
Iterations, AttributeCount).TotalMilliseconds));
Console.WriteLine("-----------------------------");
}
}
static TimeSpan GetExecutionTimeSpan(Func<int, string> f, int
Iterations, int
AttributeCount)
{
DateTime Start = DateTime.Now;
for (int i = 0; i
< Iterations; i++)
f(AttributeCount);
return DateTime.Now - Start;
}
static string
RenderWithString(int
AttributeCount)
{
string s = "<html";
for (int i = 0; i
< AttributeCount; i++)
s += " size=\"" +
(AttributeCount + 1) + "\"";
s += ">";
return s;
}
static string
RenderWithStringBuilder(int
AttributeCount)
{
StringBuilder sb = new StringBuilder("<html");
for (int i = 0; i
< AttributeCount; i++)
sb.Append(" size=\"").Append(AttributeCount
+ 1).Append("\"");
sb.Append(">");
return sb.ToString();
}
}
}
No comments:
Post a Comment