FrameRate Demo With No Garbage Generated or collected from numerical text in c#.

Edit: fixed a bug that was causing a precision error.

I fixed a decimal placement bug shown in the picture below as well as a error in the algorithm. Anyways the point is it works gc wise.
It’s not perfect minor floating point errors are inherent to it, and im sure there are still some edge case bugs, but if you want to see when you are actually getting allocations other then from text in real time, its useful.

The framerate example class has simple bool options as well in this case to turn on and off stuff.

On the left is regular string builder, on the right is my rigged up wrapper, you can see their are no allocations from the FrameRate output itself.

Can you explain how this one works different to the default stringbuilder and why it’s preferable? I have no clue about this stuff actually, I guess it would be nice if the stringbuilder was smart about stuff that is repeated often and don’t throw the old things away?

I made a couple minor fixes to the class, to fix a math error which seemed to be due to a bug, that i left in from a larger test project. I just re-posted the 3 class files instead of the whole project.

FrameRate class is a bit over complicated at a glance to see how you’ve built the strings

Well i really did it like that so you could change the bool in the example and see the difference between a regular string builders output and this versions but i maybe put to many examples in there.

I couldnt figure out if there was a better way to format the string the way I wanted it to display but this did the trick.

They way you did it or some other inventive manner of doing that. Is probably required for formatting numerical things to a specific manner of display, If one wants to not create garbage.

The AppendTrim function itself limits the decimal places to 3 that’s about all the custom formatting i added. Which was just done as a example to show how you could alter the outputted text mathematically, by simply breaking the while loop after a specific number of iterations.

I suppose since this is somewhat of a hack around the root of the problem which unfortunately is in dot net. Its pretty much create your own formatting at least for numerical display

Can you explain how this one works different to the default stringbuilder

This basically wraps a StringBuilder and intercepts the numerical calls and does them instead that’s about the jist of it, well there is a little more.
It additionally keeps a couple extra static swaping string builders around in case a big capacity change occurs in one of them so it doesn’t cause garbage to escape in that manner. The operators allow you to use it with a regular StringBuilder or swap one into or out of it if need be or for convenience.

and why it’s preferable?

I tried quite a few different peoples solutions, some that dug very deep. All of them show the same problem, most all of them missed the root cause. Which was that numbers being converted to strings even with stringbuilder, simply create temporary garbage no matter what.That garbage can and will be marked and swept by the gc when enough garbage that is markable builds up. It then at some point causes a GC collection to occur that for the user this appears as a stutter in a game, which it is.Your entire app must wait for the GC to finish taking out the trash. While not a big deal for say a calculator on your desktop. For a game going at 60fps or more its very noticeable.

For the game programmer it makes it hard to differentiate in real time at a glance when something else that he is doing creates a GC problem when your very informational numerical displayed output is also causing collections.

To think of it simply, its like a temporary object going out of scope, each time you turn a number into a character via c#.

Even though it is said that char and numerics are primitive value types when it comes to conversion. We can see in the framerate test given (by switching on the regular stringbuilder and running with no fixed timestep ) that this is not what you see what you see is garbage and collections.

Some where deep down below StringBuilder and String, a temp character object is created and forgotten for each numerical value changed to a character. This is c# wide not limited to monogame.

The reason this works is we never actually ask for a conversion at all, we mathematically calculate the numerical character ourselves and only allow a character to be created. Until we let our stringbuilder go out of scope or call new on it. We wont be allowing the gc to mark it for sweeping.Unfortunately StringBuilder and Strings, underlying ToString conversion itself, needs to actually be re-written internally within dot net, for a proper fix to the problem. Because this does work im like 90% sure this is actually a unrealized bug within .net.

I spent a good amount of time attempting to make this class have all the functionality of a regular string e.g. MyStringBuilder = “some variable” + 10.5 + newline; Which yielded unfavorable results.While this was possible, it wasn’t ‘properly’ possible due to the rules of operator overloading being a little to loose and not strict enough to allow it to work without generating garbage, and not really worth it even with a regular string builder, because of the extra stuff involved.

Take care to when altering some of those that use the “static sb” though while they may look noob or unnecessary. They maybe in there to keep the reference to the characters alive, during a copy operation or prevent a de-allocation of a entire string builder itself via a collect at a undesirable time.
Though its been a bit of time since i worked on it. I tend to get a working version then stash it away then use it a few times before i get it to were im satisfied its fairly dependable, but that isn’t really the case here.

Ya sorry its still pretty raw / rough though. You will probably need to tweek it for a bit as you use it and you may find bugs as well. I would keep a separate test class though for changes made, to test it at very high iteration speed.

This is actually the only test case for practical use i made for it so far. Too boot its a newer class not based on anything i really fully hashed out previously, and its trimmed way down from the original which was a huge / sloppy project for pure experimenting.

Just don’t overdo it on adding operator overloading it’s a waste of time to try to make it work like a string “a” + “b”, it starts to become circularly futile either by performance or function.

i added this into all the constructors as well, i dunno why i didn’t before. I hope i didn’t have a reason not to lol i honestly can’t remember if i purposely didn’t put them in or not.

The below returns a live reference however this is not a new copy but a actual reference.
Meaning if its saved and acted upon, it can alter the original which can i suppose cause confusion or even possibly muck something up, if the user doesn’t get whats going on.

Ya i suppose you could write all kinds of your own line data formatting’s using the index’s.

I actually have another class i was working on a while back. That is basically just a rewritten spritebatch im planning to rewrite it in some way eventually again. To control drawstring output better. In fact i have a couple but they all are more a jumbled mess of tests then organized classes.

The idea though was to simply be able to get end vector returned from were the last DrawString ends at maximum or save it each draw and limit the size of the draw area. So you could do text outputs like that to were they didn’t get that jitter basically like appending with some limiting. It works so far its just a mess though of test methods and test classes.

This is the March 17th 2017 no garbage string builder class it represents a number of improvements.

(you can alternately just copy paste it, as its straight c# code.)

It adds a number of fixes.

The primary fix in this version is.

A fix to high order precision errors on floats and doubles that was creating a annoying precision loss.
The old version was actually compounding that error. So i basically shift all the decimals into the integer range now.

Additionally.

Calls can be chained like stringbuilder does like so.
myMessege.Append( “\n the number is " ).Append( 5 ).Append(”\n");

Trailing zeros are cut.

Some additional things will be added later these will probably be in the form of nicetys, formating or optimizations ect, I think most of the major bugs are out whittled out of it at this point.

Sorry kosmos append wasn’t in this one. I never use AppendAt and forgot it wasn’t in this one.