我对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);

最佳答案

不知道string1string2的大小是不可能的。

通过调用 AppendFormat ,它将在给定格式字符串的长度和将要插入的字符串的情况下,仅对缓冲区进行一次预分配,然后将所有内容连接起来并将其插入到缓冲区中。对于非常大的字符串,这比单独调用 Append 更为有利,后者可能导致缓冲区扩展多次。

但是,对Append的三个调用可能会触发缓冲区的增长,也可能不会触发缓冲区的增长,并且每次调用都会执行检查。如果字符串足够小并且没有触发缓冲区扩展,那么它将比对AppendFormat的调用更快,因为它不必解析格式字符串来确定在哪里进行替换。

需要更多数据才能确定答案

应该注意的是,关于使用静态 Concat method on the String class的讨论很少(使用AppendWithCapacityJon'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/

10-14 15:00