在c# . net中,StringBuilder相对于concat操作符+快了多少?
本文关键字:操作符 多少 concat 相对于 net StringBuilder | 更新日期: 2023-09-27 17:51:04
c# .Net中StringBuilder相对于concat操作符+快了多少它是如何在低水平上比concat工作得更快的?
微软开发者网络有一个很好的对比:
虽然StringBuilder和String都表示序列字符,它们的实现方式不同。字符串是不可变的类型。也就是说,每个看起来修改String对象的操作实际上创建了一个新的字符串
例如,调用String。下面c#中的Concat方法这个示例似乎要更改名为value的字符串变量的值。实际上,Concat方法返回的值对象具有不同的值和地址来自传递给方法的值对象。注意,该示例必须使用/unsafe编译器进行编译选择。对于执行大量字符串操作的例程(例如作为在循环中多次修改字符串的应用程序,修改a字符串重复会导致显著的性能损失。的另一种方法是使用StringBuilder,它是一个可变字符串类。可变性意味着一旦类的实例被创建,可以通过追加、删除、替换或插入来修改它字符。StringBuilder对象维护一个缓冲区来容纳扩展到字符串。新数据被追加到缓冲区是可用的;否则,将分配一个新的更大的缓冲区,数据来自原缓冲区被复制到新缓冲区,新数据被保存然后附加到新的缓冲区。
String
的推荐用法为:
-
当您的应用程序将对字符串进行的更改数量非常小时。在这些情况下,与
String
相比,StringBuilder
可能提供微不足道的性能改进或没有性能改进。(由于StringBuilder
处理其缓冲区的方式) -
当您执行固定数量的连接操作时,特别是对于
String
字面值。 -
当您在构建
String
时必须执行广泛的搜索操作。StringBuilder
缺少IndexOf
或StartsWith
等搜索方法。对于这些操作,您必须将StringBuilder
对象转换为String
,这可能会降低性能。
StringBuilder
的推荐用法:
-
当您期望应用程序在设计时对字符串进行未知数量的更改时(例如循环/随机数字符串)
-
当您期望您的应用程序对
string
进行重大更改时。
所以问题真的不应该是"哪个性能更好",而应该是"在哪种情况下一个比另一个更理想?"
为了对比另一个答案,这里有一个例子,显示在我的计算机上连接速度快了大约20%。
public static void ConcatTest()
{
int NumConcatenations = 10000000;
const string Postfix = "postfix_";
/** + Operator concatenation **/
var sw = Stopwatch.StartNew();
for (int x = 0; x < NumConcatenations; x++)
{
var concatResult = string.Empty;
for (int i = 0; i < 2; i++)
{
concatResult += Postfix;
}
}
var plusOperatorTime = sw.ElapsedMilliseconds;
Console.WriteLine();
sw.Reset();
/** StringBuilder concatenation **/
sw.Start();
for (int x = 0; x < NumConcatenations; x++)
{
var builder = new StringBuilder(string.Empty);
for (int i = 0; i < 2; i++)
{
builder.Append(Postfix);
}
}
var stringBuilderTime = sw.ElapsedMilliseconds;
Console.WriteLine(
"Concatenation with + operator took {0} ms, stringbuilder took {1} ms",
plusOperatorTime,
stringBuilderTime);
Console.ReadLine();
}
您是将小说中的单词连接成一本书,还是将一百万个姓和名对连接成全名?你的使用情况决定了哪个更快。测试你的具体实现是唯一确定的方法。
哇…我测量的是100倍的性能差异。Stringbuilder要快得多。请随时告诉我代码有什么问题。
在我的系统上:+的200ms vs stringbuilder的2ms。
static void Main(string[] args)
{
int NumConcatenations = 10000;
const string Postfix = "postfix_";
var concatResult = string.Empty;
/** + Operator concatenation **/
var sw = Stopwatch.StartNew();
for (int i = 0; i < NumConcatenations; i++)
{
concatResult += Postfix;
}
var plusOperatorTime = sw.ElapsedMilliseconds;
Console.WriteLine();
sw.Reset();
/** StringBuilder concatenation **/
var builder = new StringBuilder(string.Empty);
sw.Start();
for (int i = 0; i < NumConcatenations; i++)
{
builder.Append(Postfix);
}
var stringBuilderTime = sw.ElapsedMilliseconds;
Debug.Assert(concatResult.Length == builder.ToString().Length);
Console.WriteLine(
"Concatenation with + operator took {0} ms, stringbuilder took {1} ms",
plusOperatorTime,
stringBuilderTime);
Console.ReadLine();
}