Jump to content
  • Advertisement
Sign in to follow this  
SeeMe

[C#] GC and .tostring() method

This topic is 4537 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I have a simple question : How to avoid a temporary string variable declaration if I want to send a Float variable to a string. Exemple :

float fps;
string strFPS;
fps = 0f;

for (int a = 0; a <= 1000000; a++)
{
   fps++;
   strFPS = ((int)fps).ToString();
}



This simple exemple, will alocate 1000000 temporary string. A a game main boucle it could cause the GC to slow down from time to time to free up some memory ! Is there a way to sent my float value to the global string, without this anoying hiden string creation at each loop iteration ? Tx you !!!

Share this post


Link to post
Share on other sites
Advertisement
Hello,

It clearly seems that its the .ToString() method the create a temporary String before sending it the Global string.
So StringBuilder can't help me here.

I will have to build a "'number' to string" function that is using a static string for buffering !

Kind regards,

Share this post


Link to post
Share on other sites
C# strings are immutable (can't be modified once created), so you may wish to store a character array instead. It'll be a bit of a bother, but between a MemoryStream, a StreamWriter and a character array, you should be able to do what you want. Hopefully someone else will know a better way.

Share this post


Link to post
Share on other sites
If you declare your variable like that:
string strFPS;

you can only change it by creating a new string object and assigning the new string object to strFPS.


If you want to avoid object creation you need a variable of a mutable type like:
StringBuilder strFPS;
// stuff here
{
strFPS.length=0;
strFPS.append(yourfloat);
}

Share this post


Link to post
Share on other sites
Hello,

Tx for trying, but no, it's not true this code will also instanciate 10.000 temporary string (Following CLR Profiler) :



private StringBuilder sb = new StringBuilder();
private int a = 0;

public void Run()
{
for (int b = 0; b < 10000; b++)
{
sb.Length = 0;
sb.Append(a);
}
}





It seems that its the '.ToString()' method from the integer variable that is using a temporary String.

So :

A (Integer) --> Call to .ToString() --> MyTempString with A value --> Sent to StringBuilder !

Share this post


Link to post
Share on other sites
MSDN on StringBuilder.Append(int)
Quote:
Remarks:
Int32.ToString is used to get a string representation of value. The capacity of this instance is adjusted as needed.

That's just stupid :(

You could use StringBuilder.Append(char) and write the int->string conversion yourself, that would probably work.

On the other hand GC for short-lived objects is usually quite cheap, so it might not be worth avoiding it.

Share this post


Link to post
Share on other sites
Yes indead, it's really strange.

I could let the GC do its job, but when I see the CLRprofiler log it scares me : 100000 string instanciated for a size of 2.6Mbytes every 2 seconds !

It makes 78Mbytes by minutes allocated for .... nothing !
It's allocating a lot for nothing ...

Share this post


Link to post
Share on other sites
There are all kinds of tricks involved in writing garbage collectors - one of them is to exploit the knowledge that the longer an object has been in use, the less likely it is to need garbage collecting - which would make a well written GC perform well in the case you describe.

In general, write C# and let the GC do it's job for most code and write C++ for time critical code (and hook them together using C++CLR).

Share this post


Link to post
Share on other sites
the same would happen if you used a std::string declared in a function. It would get created and destroyed, but allocated and deallocated quickly.

Because the string object is a class rather then a struct, it is likely that it's stored in the heap (I dunno, the CLR might make exceptions / specific optimisations for the string class). But because the graph is shallow (as it's declared in the function) it is easy for the GC to pick up in a single pass. It's the longer lived memory allocations you need to be careful of.

For instance "string strFPS;" - you only need to declare strFPS if you intend on using it more then once. Otherwise just send it across to another function with a .ToString(), so the instance is just anon.

To make your code friendlier for the GC, try and keep as few references to the string as possible. The less references to a variable it has to check, the more likely it can get rid of it quickly.

Unless your applications memory footprint is steadily climbing just from your original example, there is no need to stress out about this stuff.

It's good you are using the CLR profiler and all that, but I would worry about this issue only if it becomes apparent that it is a problem later on when more of your game is done. There is always a danger of focusing too much on this kind of thing when it's not really a problem - it's just different from what you are used too.

I think the biggest problem some of the C++ guys have when it comes to C#, Java and the like is trusting what is going on behind the scenes because they are so used to controlling every single detail. I know it took me a while to get used to the idea, and learn optimisation techinques for C# that might not make sense in C++.

A general rule of thumb applies - do timings etc to see what the effect of things is. Just looking at the allocated / destroyed metric on it's own could be misleading without time taken to complete a loop and interuptions of the GC. So I would try and put this to the back of your mind and just get on with whatever you are doing.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!