在 stringbuilder 上调用 append 时,我们是否将字符串添加到堆中?

When calling append on stringbuilder, are we adding strings to the heap?

我想知道在 C# 中使用 stringbuilder 对内存使用的好处。

如果您遇到以下情况:

    var strBuilder = new StringBuilder();

        for(int i=0;i<1000;i++)
        {
           strBuilder.Append(i); /// is this not calling i.ToString(); ???
           strBuilder.Append(','); /// this i character comma
           strBuilder.Append(" and "); /// this is creating a new string " and " right ?
           strBuilder.Append(','); // this is a character comma, and not a string, this is value type
        }

我的问题如下:每次我们调用append方法时,我们不是在创建一个字符串,然后从stringBuilder中使用,追加并添加到内部字符数组-缓冲区吗?

我假设每当我们追加一些东西时,我们也在创建要追加的字符串,然后它就坐在堆上,等待被垃圾收集。 这不是对堆的性能影响吗?

是的,每次都会创建 strings 的新实例,但使用的是 StringBuilder 实例的相同引用。仅将 StringBuilder 设置为 null 会更改 StringBuilder 的引用。

are we not creating a string that is then used from the stringBuilder, to be appended and added to the internal character array - buffer ?

在您的正确示例中,是的。必须首先分配字符串,然后将其添加到内部缓冲区。但是假设您有一个 class,其中包含一堆已经实例化的属性,并且您想要将它们连接在一起。使用 StringBuilder 附加每一个可以在连接期间节省不必要的分配。

I assume that whenever we append something, we are also creating the string that is to be appended and then this is sitting on the heap, waiting to become garbage collected. Is this not a perfomance hit for the heap ?

构建器内部使用该字符串:

 unsafe
 {
         fixed (char* valuePtr = value)
         fixed (char* destPtr = &chunkChars[chunkLength])
         string.wstrcpy(destPtr, valuePtr, valueLen);
  }

然后丢弃并符合收集条件。我不会将堆上的 string 称为性能影响,但它会增加堆的大小,具体取决于您拥有多少分配。

请注意,在您的循环中,没有理由为每次迭代分配这些字符串。在循环外声明它们可以节省你的时间。