StringBuilder
如何工作?
它在内部做什么?它使用不安全的代码吗?
而且为什么这么快(与+
运算符相比)?
最佳答案
当您使用+运算符构建字符串时:
string s = "01";
s += "02";
s += "03";
s += "04";
然后在第一个串联中,我们创建一个长度为4的新字符串,并在其中复制“01”和“02”,即复制了四个字符。在第二个串联中,我们制作了一个长度为6的新字符串,并在其中复制了“0102”和“03”-复制了六个字符。在第三个concat中,我们制作了一个长度为8的字符串,并将“010203”和“04”复制到其中-复制了八个字符。到目前为止,已经为该八个字符的字符串复制了总共4 + 6 + 8 = 18个字符。继续。
...
s += "99";
在第98个concat上,我们制作了一个长度为198的字符串,并将“010203 ... 98”和“99”复制到其中。为了得到这198个字符串,总共给我们4 + 6 + 8 + ... + 198 =很多。
字符串生成器不会执行所有复制操作。相反,它维护一个可变数组,该数组希望比最终字符串大,并在必要时向数组中填充新内容。
当猜测错误并且阵列已满时会发生什么?有两种策略。在该框架的先前版本中,字符串生成器在数组满时重新分配并复制该数组,并将其大小加倍。在新的实现中,字符串生成器维护一个相对较小数组的链表,并在旧数组填满后将新数组追加到列表的末尾。
同样,如您所料,字符串生成器可以使用“不安全”代码来欺骗技巧,以提高其性能。例如,将新数据写入数组的代码可以检查数组写入是否在范围之内。通过关闭安全系统,可以避免进行每次写入检查,否则可能会插入抖动以验证对阵列的每次写入是否安全。字符串生成器执行了许多这类技巧,例如确保重复使用缓冲区而不是重新分配缓冲区,确保避免不必要的安全检查等等。我建议您不要使用这些恶作剧,除非您真的擅长正确编写不安全的代码,并且确实需要提高性能的每一点。