在类中将StringBuilder
作为成员变量,在类方法中使用它来连接字符串是否高效(或必要)?
还是在这些操作之前使用new StringBuilder()
?
如果有一个可用的StringBuilder
,我认为这样做是高效的。
在类中将StringBuilder
作为成员变量,在类方法中使用它来连接字符串是否高效(或必要)?
还是在这些操作之前使用new StringBuilder()
?
如果有一个可用的StringBuilder
,我认为这样做是高效的。
这是一个有趣的问题,已经研究过。
答案是,在极端测试条件下共享单个实例并重复使用比每次创建新的StringBuilder
更有效率,但在大多数情况下几乎不需要这样做,而且可能是一个坏主意。其他考虑因素如线程安全通常比过早进行微观优化更为重要。
以下代码来自链接文章,进行了高度人为的性能测试:
using System;
using System.Diagnostics;
using System.Text;
class Program
{
static string Method1()
{
StringBuilder builder = new StringBuilder();
foreach (string value in _array)
builder.Append(value);
return builder.ToString();
}
static StringBuilder _builder = new StringBuilder();
static string Method2()
{
StringBuilder builder = _builder;
builder.Clear();
foreach (string value in _array)
builder.Append(value);
return builder.ToString();
}
static string[] _array = { "dot", "net", "perls", "string", "array" };
const int _max = 1000000;
static void Main()
{
Method1();
Method2();
// Version 1: use new StringBuilder each time.
var s1 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
Method1();
}
s1.Stop();
// Version 2: reuse a single StringBuilder instance.
var s2 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
Method2();
}
s2.Stop();
Console.WriteLine(s1.Elapsed.TotalMilliseconds);
Console.WriteLine(s2.Elapsed.TotalMilliseconds);
Console.Read();
}
}
以下是我刚刚运行的结果:
StringBuilder
确实更好,但实际上并非如此。因此,人们会使用一个类成员StringBuilder
,没有性能提升,但可能会在未来出现线程问题,或者如果一个方法操作内容而另一个方法不希望它,则会产生错误结果。这引入了不必要的复杂性和依赖关系。StringBuilder
是创建字符串的工具。由于它是该类型的属性,而不是StringBuilder
本身的属性,因此可以将其存储为类中的字段。 - Tim Schmelter
StringBuilder
初始化并不昂贵,不要优化错误的部分。 - Tim SchmelterStringBuilder
不应该太昂贵。如果这是一个问题,您可以随时创建一个构建器池来使用。通常,如果您想要线程安全性,则创建类级成员会受到影响。 - Yuval ItzchakovStringBuilder
的选项,这是在使用局部变量时不可能的。通常情况下,我会尽可能地限制变量的范围和可访问性。 - Tim Schmelter