StringBuilder如何在C#内部工作? [英] How does StringBuilder work internally in C#?

查看:81
本文介绍了StringBuilder如何在C#内部工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

StringBuilder 如何工作?

内部有什么作用?它使用不安全的代码吗?
为什么这么快(与 + 运算符相比)?

What does it do internally? Does it use unsafe code? And why is it so fast (compared to the + operator)?

推荐答案

使用+运算符构建字符串时:

When you use the + operator to build up a string:

string s = "01";
s += "02";
s += "03";
s += "04";

然后在第一个连接中创建一个新的长度为4的字符串,并复制 01和 02 中复制了四个字符。在第二个连接中,我们创建了一个长度为6的新字符串,并在其中复制了 0102和 03-复制了六个字符。在第三个concat中,我们制作了一个长度为8的字符串,并将 010203和 04复制到其中-复制了八个字符。到目前为止,已经为该八个字符的字符串复制了总共4 + 6 + 8 = 18个字符。继续。

then on the first concatenation we make a new string of length four and copy "01" and "02" into it -- four characters are copied. On the second concatenation we make a new string of length six and copy "0102" and "03" into it -- six characters are copied. On the third concat, we make a string of length eight and copy "010203" and "04" into it -- eight characters are copied. So far a total of 4 + 6 + 8 = 18 characters have been copied for this eight-character string. Keep going.

...
s += "99";

在第98个concat上,我们制作了一个长度为198的字符串,并复制 010203 ... 98,然后 99进去了。为了使这198个字符串成为可能,我们总共有4 + 6 + 8 + ... + 198 =多个。

On the 98th concat we make a string of length 198 and copy "010203...98" and "99" into it. That gives us a total of 4 + 6 + 8 + ... + 198 = a lot, in order to make this 198 character string.

字符串生成器不会做所有的复制。相反,它维护一个可变数组,该数组希望比最终字符串大,并在必要时向数组中填充新内容。

A string builder doesn't do all that copying. Rather, it maintains a mutable array that is hoped to be larger than the final string, and stuffs new things into the array as necessary.

当猜测错误并且数组已满时会发生什么?有两种策略。在该框架的早期版本中,字符串生成器在数组满时重新分配并复制该数组,并将其大小加倍。在新的实现中,字符串生成器维护一个相对较小数组的链表,并在旧数组填满后将新数组追加到列表的末尾。

What happens when the guess is wrong and the array gets full? There are two strategies. In the previous version of the framework, the string builder reallocated and copied the array when it got full, and doubled its size. In the new implementation, the string builder maintains a linked list of relatively small arrays, and appends a new array onto the end of the list when the old one gets full.

此外,正如您所猜想的那样,字符串生成器可以使用不安全代码来欺骗技巧,以提高其性能。例如,将新数据写入数组的代码可以检查数组写入是否在范围之内。通过关闭安全系统,可以避免执行每次写入检查,否则可能会插入抖动,从而验证对阵列的每次写入是否安全。字符串生成器执行了许多这类技巧,以确保确保重用缓冲区而不是重新分配缓冲区,确保避免不必要的安全检查等等。我建议您不要使用这种恶作剧,除非您真的擅长正确编写不安全的代码,并且确实需要提高性能的每一点。

Also, as you have conjectured, the string builder can do tricks with "unsafe" code to improve its performance. For example, the code which writes the new data into the array can already have checked that the array write is going to be within bounds. By turning off the safety system it can avoid the per-write check that the jitter might otherwise insert to verify that every write to the array is safe. The string builder does a number of these sorts of tricks to do things like ensuring that buffers are reused rather than reallocated, ensuring that unnecessary safety checks are avoided, and so on. I recommend against these sorts of shenanigans unless you are really good at writing unsafe code correctly, and really do need to eke out every last bit of performance.

这篇关于StringBuilder如何在C#内部工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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