- Home /
Display numbers in UI.Text Garbage Free?
Hi!
I've been reading a lot of forums and discussions in regards to converting a number to string garbage free.
At the moment any of my attempts to display a number in a UI.Text text created garbage, so this triggered the Garbage Collector and I get some performance hiccups on mobile when that happens.
Basically, I want to display the number of coins the player collected and sometimes he can collect more of them in quick succession. That is when the hiccups occur.
Basically:
myUIText.text = myIntValue.ToString();
Generates garbage.
Using StringBuilder is no good either, because this one generates garbage when converting ToString()
A popular fix is generating all the strings before hand and just placing those in the UI.Text.text field.
string[] allNumbers = new string[100] {"1", "2", .... etc};
myUIText.text = allNumbers[myIntValue];
But this is not good when you have a big range of numbers.
I saw some other clever tries to fix this, but some of them are obsolete nowadays for some reason.
Is there any way to display a number in UI.Text without garbage being generated?
Answer by TheSOULDev · Sep 14, 2017 at 08:29 PM
I don't know how you'd turn a number into a string without garbage when you're one format into another, which by default, because there is no explicit function for it, will create garbage.
It's the easiest to implicitly convert numbers into strings, like this:
int number = 13;
string Sentence = "John has " + number + " apples";
It will print John has 13 apples.
Trying to optimize the above is microoptimization and even though it is useless, it is also bad to try and make something good better risking to break a lot of stuff. I don't thing there is a single way to convert any number into a string without generating garbage besides caching which is a huge memory hog. Stick to the basics.
Hi @TheSOULDev Thanks for your answer.
However, what the example you gave is equivalent to my first example (as in, the ToString() method will be called anyway you write it). $$anonymous$$oreover I explained clearly the reason I need to get rid of garbage here. Optimizations for hiccups and fps drops during gameplay are not useless like you say. I'm sure this is the cause for the hiccups I'm experiencing, because aside from profiling I actually removed the line of code that converts the int to string and I immediately saw the improvement.
There is absolutely no reason implicitly converting numbers into strings generates enough garbage to cause hiccups on any 2010 and newer hardware. You should look for problems elsewhere, especially because you just assumed that string conversion is a problem without even consulting or at least showing us the profiler.
The biggest mistake you can make is try to reinvent the wheel. Unity would have a lot more problems than it actually does if number to string conversion bloated it enough to cause hiccups.
I don't know how you display the coin text you're talking about, but I can type letter by letter rich text with a delay of 0.02s (essentially every frame) without any significant drop. However, you could try creating a char array and then run a function that will edit that char array (of a fixed size, of course) when your score is changed and also run the string update. This would mean that by changing numbers you aren't throwing away the previous data field, but you would somehow need to regulate which part of the char array you're sending to the string that represents your score, which shouldn't be too hard. But I don't know if modulo operations and integer division would be faster than ToString(), you'll have to find that out for yourself.
Hei again!
$$anonymous$$y mistake! I was doing the conversion to string on the same line as assigning the string to the UI Text and I assumed it was because of the conversion since both tests pointed to this line.
In fact, for some reason, changing the UI.Text.text field was creating hiccup. I unchecked all the Raycast Targets from UI objects in the gameplay menu (as well, usually I do this everywhere, except cases in which I need that) and it fixed the issue perfectly, even though, like you said, I have a little garbage.
You were right, I was wrong :D
Thanks for the info!
Answer by ransomink · Sep 15, 2017 at 01:20 AM
I can't see the .ToString()
method to be your sole reason for hiccups. You should use the profiler during game testing to see what scripts and methods are called during spiking.
Many games—mine included—have a plethora of text generated/appearing every frame, so it's weird for that to be an issue. It can, however, be how you're displaying the text...
Thank you for your answer!
It was a different issue like you said. Profiler didn't show much anyway, usually I catch all issues in there. Even profiling the device didn't show much either. I was seeing some little physics spikes, but didn't make sense (wasn't on ProcessReports, but on Processing so it wasn't caused by my code directly). In fact the Physics would update, or something, each time I was updating the text field of a UI.Text. I unchecked the Raycast Target toggle on the Text component and everything is smooth now.
Your answer
Follow this Question
Related Questions
GC Allocation with new array length 0 Answers
force and delay Garbage Collection 7 Answers
Optimize (Garbage Collection, Memory usage) 1 Answer
Reasonable heap alloc. per second and total ? 0 Answers
Draw Call Optimization 3 Answers