StringBuilder.Append 与 StringBuilder.AppendFormat [英] StringBuilder.Append Vs StringBuilder.AppendFormat

查看:38
本文介绍了StringBuilder.Append 与 StringBuilder.AppendFormat的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道 StringBuilder,我有一个问题希望社区能够解释.

I was wondering about StringBuilder and I've got a question that I was hoping the community would be able to explain.

让我们忘记代码可读性,哪些更快,为什么?

Let's just forget about code readability, which of these is faster and why?

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 的大小.

It's impossible to say, not knowing the size of string1 and string2.

调用 AppendFormat,它会根据格式字符串的长度和将要插入的字符串预先分配一次缓冲区,然后连接所有内容并将其插入缓冲区.对于非常大的字符串,这将优于单独调用 Append 这可能会导致缓冲区多次扩展.

With the call to AppendFormat, it will preallocate the buffer just once given the length of the format string and the strings that will be inserted and then concatenate everything and insert it into the buffer. For very large strings, this will be advantageous over separate calls to Append which might cause the buffer to expand multiple times.

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

However, the three calls to Append might or might not trigger growth of the buffer and that check is performed each call. If the strings are small enough and no buffer expansion is triggered, then it will be faster than the call to AppendFormat because it won't have to parse the format string to figure out where to do the replacements.

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

应该注意的是,很少讨论使用静态String 类上的 >Concat 方法 (Jon 的回答 使用 AppendWithCapacity 提醒了我这一点).他的测试结果表明这是最好的情况(假设您不必利用特定的格式说明符).String.Concat 做同样的事情,因为它将预先确定要连接的字符串的长度并预分配缓冲区(由于通过参数循环构造,开销略高).它的性能将与 Jon 的 AppendWithCapacity 方法相媲美.

It should be noted that there is little discussion of using the static Concat method on the String class (Jon's answer using AppendWithCapacity reminded me of this). His test results show that to be the best case (assuming you don't have to take advantage of specific format specifier). String.Concat does the same thing in that it will predetermine the length of the strings to concatenate and preallocate the buffer (with slightly more overhead due to looping constructs through the parameters). It's performance is going to be comparable to Jon's AppendWithCapacity method.

或者,只是简单的加法运算符,因为它无论如何都会编译为对 String.Concat 的调用,但需要注意的是所有加法都在同一个表达式中:

Or, just the plain addition operator, since it compiles to a call to String.Concat anyways, with the caveat that all of the additions are in the same expression:

// 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,000StringBuilder 实例,GC 很可能会在第二次测试期间介入并阻碍其计时.

You need to run your test cases in separate runs (or at the least, perform a GC between the measuring of separate test runs). The reason for this is that if you do say, 1,000,000 runs, creating a new StringBuilder in each iteration of the loop for one test, and then you run the next test that loops the same number of times, creating an additional 1,000,000 StringBuilder instances, the GC will more than likely step in during the second test and hinder its timing.

这篇关于StringBuilder.Append 与 StringBuilder.AppendFormat的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆