我对StringBuilder感到疑惑,我有一个问题,希望社区能够解释。
让我们忘记代码的可读性,哪些是更快的,为什么?StringBuilder.Append
:
StringBuilder sb = new StringBuilder();
sb.Append(string1);
sb.Append("----");
sb.Append(string2);
StringBuilder.AppendFormat
:StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}----{1}",string1,string2);
最佳答案
不知道string1
和string2
的大小是不可能的。
通过调用 AppendFormat
,它将在给定格式字符串的长度和将要插入的字符串的情况下,仅对缓冲区进行一次预分配,然后将所有内容连接起来并将其插入到缓冲区中。对于非常大的字符串,这比单独调用 Append
更为有利,后者可能导致缓冲区扩展多次。
但是,对Append
的三个调用可能会触发缓冲区的增长,也可能不会触发缓冲区的增长,并且每次调用都会执行检查。如果字符串足够小并且没有触发缓冲区扩展,那么它将比对AppendFormat
的调用更快,因为它不必解析格式字符串来确定在哪里进行替换。
需要更多数据才能确定答案
应该注意的是,关于使用静态 Concat
method on the String
class的讨论很少(使用AppendWithCapacity
的Jon's answer提醒了我这一点)。他的测试结果表明,这是最好的情况(假设您不必利用特定的格式说明符)。 String.Concat
具有相同的作用,因为它将预先确定要连接和预分配缓冲区的字符串的长度(由于循环遍历参数而导致的开销会稍微增加)。它的性能将与Jon的AppendWithCapacity
方法相当。
或者,只是普通的加法运算符,因为它无论如何都会编译为对String.Concat
的调用,但需要注意的是所有加法都在同一表达式中:
// One call to String.Concat.
string result = a + b + c;
不是
// Two calls to String.Concat.
string result = a + b;
result = result + c;
对于所有张贴测试代码的人
您需要在单独的运行中运行测试用例(或者至少在两次独立的测试运行之间执行GC)。这样做的原因是,如果您说要运行1,000,000次,则在一个测试的循环的每次迭代中创建一个新的
StringBuilder
,然后运行下一个循环相同次数的测试,从而创建另外的1,000,000 StringBuilder
实例, GC在第二次测试期间很有可能会介入并阻碍其时机。关于c# - StringBuilder.Append与StringBuilder.AppendFormat,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/710504/