字符串不变性和.net中的实习

时间:2012-04-24 01:15:33

标签: .net string string-interning

我打算在this other SO question上发布一个答案,但是有人在StringBuilder课程中领先于我,无论如何,离题......

我理解.NET中的字符串是不可变的,因此创建字符串并修改它实际上会在内存中创建两个不同的字符串,这与StringBuilder Class相反,后者维护内部缓冲区并仅在ToString()致电。我也知道.NET会中断每个字符串,因此在应用程序中每个字符串只会创建一个副本。

当你将一个字符串附加到另一个字符串时,它们都在应用程序中使用,所以它们都被实习(不是吗?),不用连接运算符追加字符串的主要原因是因为你将结束完成时内存中有一大串字符串,每个字符串都比前一个大。

我了解将0123456789连接在内存中会产生以下两个字符串:

  

01234
0123456789

虽然使用StringBuilder只会产生,因为实习:

  

01234
56789

显然第二种方法对性能更好,但实际上有多好?我的意思是,如果你从一小组值中创建一个更大的字符串,我为什么要考虑StringBuilder(本身需要占用内存空间)?使用它总是好吗?或者对于何时[不]使用它有什么好的规则?

1 个答案:

答案 0 :(得分:3)

  

我也知道.NET实习每个字符串

不,你对实习有错误的想法。当您通过连接创建一个新字符串时,运行时会搜索实习字符串表以查看是否存在匹配项。这将是非常低效的,太多的CPU周期可以节省GC堆空间。

在常规.NET应用程序中实例化的唯一字符串是从头开始实习的字符串。编译器从源代码中的文字创建并添加到程序集元数据中的字符串表中的那些。您可以使用String.Intern()方法显式地实例化一个字符串,但这是非常罕见的事情。

使用StringBuilder可以避免生成太多寿命很短的临时字符串。