字符串.replace vs StringBuilder.替换为内存

本文关键字:内存 替换 StringBuilder replace vs 字符串 | 更新日期: 2023-09-27 18:13:32

我下载了一个byte[] 'raw'流,大约36MB。然后用

将其转换为字符串
string temp = System.Text.Encoding.UTF8.GetString(raw)

然后我需要将所有"'n"替换为"'r'n",所以我尝试

 string temp2 = temp.Replace("'n","'r'n")

但是它抛出了"内存不足"异常。然后我尝试用StringBuilder创建一个新的字符串:

string temp2 = new StringBuilder(temp).Replace("'n","'r'n").toString()

,它没有抛出异常。为什么首先会有内存问题(我这里只处理36MB),而且为什么StringBuilder.Replace()在另一个不起作用时工作?

字符串.replace vs StringBuilder.替换为内存

使用

string temp2 = temp.Replace("'n","'r'n")

对于字符串temp中每匹配一次"'n",系统创建一个新的字符串,替换为。

对于StringBuilder,这种情况不会发生,因为StringBuilder是可变的,所以你可以修改同一个对象,而不需要创建另一个。

例子:

temp = "test1'ntest2'ntest3'n"

With First Method (string)

string temp2 = temp.Replace("'n","'r'n")

等价于

string aux1 = "test1'r'ntest2'ntest3'n"
string aux2 = "test1'r'ntest2'r'ntest3'n"
string temp2 = "test1'r'ntest2'r'ntest3'r'n"

With Secon Method (StringBuilder)

string temp2 = new StringBuilder(temp).Replace("'n","'r'n").toString()

等价于

Stringbuilder aux = "test1'ntest2'ntest3'n"
aux = "test1'r'ntest2'ntest3'n"
aux = "test1'r'ntest2'r'ntest3'n"
aux = "test1'r'ntest2'r'ntest3'r'n"
string temp2 = aux.toString()

来自MSDN的StringBuilder:

大多数修改该类实例的方法返回a引用同一个实例,你就可以调用一个方法或属性关于参考资料。如果您想编写单个对象,这将非常方便连接连续操作的语句。

所以当你用String调用replace时,新的对象(大数据- 36MB)将被分配来创建新的字符串。但是StringBuilder访问相同的实例对象,而不创建新的。

有一个内存压力的概念,这意味着创建的临时对象越多,垃圾收集运行的次数就越多。

:StringBuilder创建更少的临时对象,增加更少的内存压力。

StringBuilder记忆代替

接下来使用StringBuilder替换循环中的字符。首先将字符串转换为StringBuilder,然后调用StringBuilder的方法。这样更快——StringBuilder类型在内部使用字符数组

字符串在c#中不可变。如果你使用String .replace()方法,系统将为每次替换创建一个String对象。StringBuilder类将帮助您避免创建对象。