OK Im nearing completion of my multiyear game, so time to optimize etc The thing that takes the most unnecessary time is string formatting I'm using StringBuilder (I have also tried standard strings) I'm caching results, trying to keep things to a minimum etc, but its time to bite the bullet and just fix the string formatting I can't understand why it generates so much garbage, esp since if the following code proposes is correct all this garbage it generates is unnecessary (I couldnt get it to compile though) https://github.com/MikePopoloski/StringFormatter What is everyone else doing?
How much string work are you doing per frame that it's a performance bottleneck? Make sure you're only updating data, like the UI/HUD, when it actually changes. TextMeshPro's objects also have a SetText() which is more performant than using .text.
The page you linked explains why there's so much garbage: StringBuilder first needs to box any value type parameters, calls ToString() on each of them, and also needs to allocate an args array, among other things. Check the ZString library, it's compatible with Unity: https://github.com/Cysharp/ZString Make sure to read their documentation thoroughly, as there are important differences to using StringBuilder and information on how to avoid allocations when passing the result to TMP.
@GroZZleR Its not a lot (I'm not doing a word processor ) but its like 0.5 msec. Yes like I wrote I am caching as much as possible. I'm not using textmeshpro, I started before this was avialable, I may change over later @Neto_Kokku thanks a lot for the link, I'll check this out first in a small project @koirat here are the methods that generate garbage with StringBuilder https://www.gavpugh.com/2010/04/01/xnac-avoiding-garbage-when-working-with-stringbuilder/ I'm sort of at a loss as to why they made it like this as its possible to do this without generating garbage
If you switch to TextMeshPro, you can also pretend like it's C you're writing and just deal with a '\0'-terminated char[] buffer. I assume you've already gone through and made sure that all the text handling is actually for text on the screen, not eg. sending information from one system to another. So the inline documentation for SetText is "This function is the same as using the text property to set the text". Then again, the implementation of SetText and the .text setters are different. I found a bug in one of them, and the dev was all like "why are you using that one and not the other one?" when I posted about it. But both are just setting the backing m_text to the input, so GC-wise there shouldn't be any difference, they're not copying anything anywhere.
OK testing results approx hopefully the codes correct as Im adapting what Ive written Zstring Code (CSharp): Startup for ( int i=0; i<N; i++ ) { zstr[i] = ZString.CreateStringBuilder(); } actual = ZString.PrepareUtf16<float>("{0:0.0}"); for ( int i=0; i<N; i++ ) { zstr[i].Clear(); zstr[i].Append( i ) // for ints or zstr[i].Append( actual.Format((float)(i * 0.1f)) ); // for floats at one decimal place = 0.0 } stringbuilder Code (CSharp): for (int i = 0; i < N; i++) { sb[i].Clear(); sb[i].AppendFormat( "{0:0.0}", (float)(i * 0.1f) ); or sb[i].Append( i ); } N = 1000, results from profiler (so not gonna be 100% accurate) StringBuilder with int GC = 31kb, time = 0.5 msec ZString with int GC 0kb, time = 0.14msec StringBuilder with float 0.0 GC = 600kb, time = 3.83 msec ZString with float 0.0 GC 33kb, time = 1.5msec I'm not sure why ZString with float is still generating garbage? Am I doing it right? I notice the parsing results are not exactly the same always for floats
Yeah this is what I do already with my text drawing I take the string and convert it into a char [] buffer;
I haven't used ZString, but at a glance, it only has zero allocations in the process of the concatenation itself. The float.ToString() part can still generate garbage.