string.replace vs StringBuilder.replace for memory [duplicate]

删除回忆录丶 提交于 2019-12-23 08:29:21

问题


I have downloaded a stream as a byte[] 'raw' that is about 36MB. I then convert that into a string with

string temp = System.Text.Encoding.UTF8.GetString(raw)

Then I need to replace all "\n" with "\r\n" so I tried

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

but it threw an "Out of Memory" exception. I then tried to create a new string with a StringBuilder:

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

and it didn't throw the exception. Why would there be a memory issue in the first place (I'm only dealing with 36MB here), but also why does StringBuilder.Replace() work when the other doesn't?


回答1:


When you use:

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

for every match of "\n" in the string temp, the system creates a new string with the replacement.

With StringBuilder this doesn't happens because StringBuilder is mutable, so you can actually modify the same object without the need to create another one.

Example:

temp = "test1\ntest2\ntest3\n"

With First Method (string)

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

is equivalent to

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()

is equivalent to

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()



回答2:


Following StringBuilder from MSDN:

Most of the methods that modify an instance of this class return a reference to that same instance, and you can call a method or property on the reference. This can be convenient if you want to write a single statement that chains successive operations.

So when you call replace with String the new object (big data - 36MB) will be allocate to create new string. But StringBuilder accessing same instance objects and does not create new one.




回答3:


There is a concept of memory pressure, meaning that the more temporary objects created, the more often garbage collection runs.

So: StringBuilder creates fewer temporary objects and adds less memory pressure.

StringBuilder Memory

Replace

We next use StringBuilder to replace characters in loops. First convert the string to a StringBuilder, and then call StringBuilder's methods. This is faster—the StringBuilder type uses character arrays internally




回答4:


String is immutable in C#. If you use string.replace() method, the system will create a String object for each replacement. StringBuilder class will help you avoid object creation.



来源:https://stackoverflow.com/questions/16539584/string-replace-vs-stringbuilder-replace-for-memory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!