测试方法
- 使用+= 和StringBuilder 分别链接字符串10次,100次,1000次,100000次并计时
- 使用 指定 capacity 和未指定capacity分别构造string builder 并循环10000000次
- 测试环境为VS2017
结论
- 处理大量的字符串链接时,超过1000,string builder快。+= 的消耗是非线性的。
- 处理少量字符串链接时,1000以内,不在意性能的情况下可以使用+=。
- 当字符串超过16个以后,构建指定缓存区大小的string builder来链接字符串要快一些。
测试1
- Link strings by +=
- Total 10
- 1 += 0ms
- 2 StringBuilder 0ms
- Total 100
- 1 += 0ms
- 2 StringBuilder 0ms
- Total 1000
- 1 += 13ms
- 2 StringBuilder 0ms
- Total 10000
- 1 += 301ms
- 2 StringBuilder 2ms
- Total 100000
- 1 += 69806ms
- 2 StringBuilder 21ms测试2
- Link strings by +=
- Total 10
- 1 += 0ms
- 2 StringBuilder 0ms
- Total 100
- 1 += 0ms
- 2 StringBuilder 0ms
- Total 1000
- 1 += 11ms
- 2 StringBuilder 0ms
- Total 10000
- 1 += 166ms
- 2 StringBuilder 1ms
- Total 100000
- 1 += 43162ms
- 2 StringBuilder 12ms测试3
- String builder with default creator: 1895ms
- String builder with capacity creator: 535ms
- String builder with default creator: 1823ms
- String builder with capacity creator: 577ms
Code1
var str = "+= i:0";
var sw = new System.Diagnostics.Stopwatch();
Console.WriteLine("Link strings by +=");
for (var total = 10; total < 1000000; total *= 10)
{
Console.WriteLine("Total " + total.ToString());
sw.Reset();
sw.Start();
for (int i = 1; i < total; i++)
{
str += ", i:" + i.ToString();
}
sw.Stop();
Console.WriteLine("1 += " + sw.ElapsedMilliseconds.ToString() + "ms");
var builder = new System.Text.StringBuilder();
builder.Append("+= i:0");
sw.Reset();
sw.Start();
for (int i = 1; i < total; i++)
{
builder.Append(", i:");
builder.Append(i.ToString());
}
str = builder.ToString();
sw.Stop();
Console.WriteLine("2 StringBuilder " + sw.ElapsedMilliseconds.ToString() + "ms");
Code2
var sw = new System.Diagnostics.Stopwatch();
sw.Reset();
sw.Start();
for (var total = 10; total < 10000000; total++)
{
var builder = new System.Text.StringBuilder(); // 默认为缓冲16
builder.Append("string 1, length : 21"); // 创建32的缓冲区,并把原来的copy过来
builder.Append("string 2, length : 21"); // 创建64的缓冲区,并把原来的copy过来
}
sw.Stop();
Console.WriteLine("String builder with default creator: " + sw.ElapsedMilliseconds.ToString() + "ms");
sw.Reset();
sw.Start();
for (var total = 10; total < 10000000; total++)
{
var builder = new System.Text.StringBuilder(64); // 直接创建64的缓冲区
builder.Append("string 1, length : 21");
builder.Append("string 2, length : 21");
}
sw.Stop();
Console.WriteLine("String builder with capacity creator: " + sw.ElapsedMilliseconds.ToString() + "ms");