- Home /
String garbage optimization question.
It's a small part, but I wonder.
It is a simple game that starts with game start -> game play -> game end. Then, for each play, initialize some string values to specific values.
ex) str1 = "Hello1"; str2 ="Hello2";
In this case, is it better to declare the const class field separately and allocate the value rather than creating and assigning the string immediately?ex) private const strHello = "Hello"; ... str1 = strHello;
There is the following score code.
scoreText.text = score.ToString("0.00") + 'm';
If the score is increased from 0.0 to 100.0 in 0.1 unit to update the text, will 1000 garbage occur?I know that StringBuilder is used to cause less string garbage. But does StringBuilder.Append() be used for even two strings? Or do you have your own criteria(3 or more, 4 or more ...) to use StringBuilder.Append()?
Honestly strings don't create that much garbage. You shouldn't worry about it.
Answer by Bunny83 · Jul 08, 2017 at 09:40 AM
To point 1:
No, string literals in your code are "interned". That means those strings are already constants. If you assign the same string to two variables they actually reference the exact same string.
string str1 = "Hello";
string str2 = "Hello";
In this case str1 and str2 will reference the same string object instance.
To point 2:
First score.ToString("0.00")
will allocate a new string with at least 4 character. Then when executing +'m'
a new string with at least 5 characters will be allocated. The 4 character string will be immediately up for garbage collection. When the text variable is replaced by a new text the old one is also up for garbage collection. So yes, if you execute that line 1000 times you will allocate two string instances each time, one with at least 4 and one with at least 5 characters.
To point 3:
You can use a StringBuilder (as long as you cache and re-use your stringbuilder). However simply using string.Format might be simpler:
scoreText.text = string.Format("{0:0.00}m", score);
Of course this would still allocate at least a 5 character string each time it's called. The format string never changes since it's an interned string literal.
Strings are immutable objects. So without some unsafe-hacks the value of a string can't be changed once created. That means when you want to change the content of a string you have to allocate a new string. @vexe wrote a garbage-free string wrapper(gstring) which could be used to reduce garbage allocation. However it might be tricky to use, has limited string feature support and most likely is not threadsafe.
'Cache' means to store a StringBuilder in a variable and use it? And the format string can not be changed means that if a string is updated, it will inevitably be allocated memory?
Right, but even when you cache the StringBuilder each string you "create" will need to be allocated as actual string.
A StringBuilder basically just uses a List<char>
internally. When you use any Append method you actually add chars to that internal list. As long as the lists capacity is not reached nothing will be allocated internally. However to finally get a string from the StringBuilder you would use the ToString method of the StringBuilder. This will create a new string, however with the final appropriate length. So you allocate the least memory possible.
Thanks for the detailed explanation! link text It is like this. Clear() and Append()
Your answer

Follow this Question
Related Questions
Display numbers in UI.Text Garbage Free? 2 Answers
Optimizing OnGUI 1 Answer
Will caching strings improve performance for animation? (and other string calls) 1 Answer
Is there something like Animator.StringToHash() but for tags? 0 Answers
Cheap options for making diffuse-lit objects "interesting" 1 Answer