Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 407
Aeon2058 Avatar asked May 14 '13 09:05

Aeon2058


People also ask

Is StringBuilder faster than string C#?

For 50,000 iterations, the regular string concatenation takes 486 milliseconds. But the stringbuilder and char pointer code don't even show up! They are running in less than 1 millisecond. This means that the regular string concatenation is at least 486 times slower than using a stringbuilder!

Why is StringBuilder more efficient C#?

Creating and initializing a new object is more expensive than appending a character to an buffer, so that is why string builder is faster, as a general rule, than string concatenation.

Does string replace create a new string?

replace() Method. This method returns a new string resulting from replacing all occurrences of old characters in the string with new characters.

Can we use string replace?

The replace() method searches a string for a value or a regular expression. The replace() method returns a new string with the value(s) replaced. The replace() method does not change the original string.


2 Answers

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()
like image 172
Dani Corretja Avatar answered Oct 03 '22 13:10

Dani Corretja


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.

like image 33
Toan Vo Avatar answered Oct 03 '22 13:10

Toan Vo