Sign in to follow this  
InferiorOlive

C#: leaving unused reference-types

Recommended Posts

InferiorOlive    1065

So, I wasn't really sure what to call this thread, so let me explain. I have an array of objects (reference-type) that I'm changing (both the contents and the number of things held by the array) once-per-update. I figure there are really two ways of handling this: 

 

1.) create a new List<object> of the type I'll be using on each cycle (or clearing at the end of each cycle, after it has served its purpose and repopulate again during the next update).

 

2.) create a finite-sized array (object[]) that only increases in size when the current maximum has been reached (so that the size of the array will only ever reach the greatest size it has ever been). This method requires that a variable be used to count how many items are currently stored in the array (because array.Count() will return the maximum size). Instead of clearing the contents or re-initializing the array, however, clearing this array (functionally), would simply require that the counting variable be set to zero. During the next update, when objects are being added, they simply replace whatever was previously in that spot.

 

The benefit of the first method is that it's empty when it's empty and only ever contains just what it needs to contain. I've heard/read (though I don't remember where), though, that dynamically-sized arrays are a little slower due to the increase in flexibility (needs to account for a broader set of circumstances). The second method doesn't use a dynamically-sized array, so, if that is true, it should hypothetically be faster. The caveat here is that it can still contain references to objects that the program is no longer using (because "clearing" the array doesn't de-reference them, but merely sets the count to zero). Because of this, the new keyword is rarely called (and is called less and less frequently as the size of the array increases).

 

My questions, then, are these: 1.) Are my assumptions about dynamic- vs. static-sized arrays correct? 2.) Which of these is likely to be faster, and is there a scenario that one may perform better (few objects held at a time) but less well in another scenario (many objects held at once). 3.) Are there other methods I'm not considering (I assume there are, but are they worth considering?)?

Share this post


Link to post
Share on other sites
ericrrichards22    2434


Just go with the List for now, and profile later if you have problems.

 

I agree, do the simplest thing first.  If it turns out to be slow, you can profile and determine the bottlenecks later.

 

Beware of making preemptive micro-optimizations that sacrifice the simplicity of your code until it is necessary.

A fair amount of the advice that you will commonly come into contact with, particularly in game programming, is from the perspective of C/C++, and, as often as not, dates from a decade ago or earlier.  C++ and C# share curly braces and a lot of keywords, but they are not exactly apples-to-apples.

Share this post


Link to post
Share on other sites
InferiorOlive    1065

Thanks for the feedback. I think, though, that the intent of my questions was not conveyed clearly.

 

I'm familiar with the perils of early-optimization, I just like to play around with the language and see what I can learn along the way). If I was really concerned about pulling a slight speed-boost, I know how to profile my project. I was really just looking for ideas concerning better ways of handling this area of programming.

 

I actually think this curiosity makes me a less-good game-programmer, because I often get interested in experimentation and language-playing. I'm okay with that, though, because programming (game or otherwise) is only (and will only ever be) a hobby of mine (I have no delusions of publishing a game or getting green-lit or anything of the sort).

Share this post


Link to post
Share on other sites
SmkViper    5396
In my experience with C# (and similar garbage-collected languages) what will usually kill you is generating lots of garbage. In other words, lots of allocations that are then quickly tossed away. Due to the large amount of garbage generated, the GC has to run more often, causing more potential hitches in your program. So if you know you have a lot of objects that are constantly allocated and thrown away, it's probably better to use a pool of them.

In your example above, assuming the objects in the list are short-lived, you could still use your list, but then make another list (the "pool") that you move inactive objects to. Then when you need a new object, you check to see if one is in the "pool". If so, take it and use it, otherwise allocate a new one.

Admittedly, .NET's generational GC has some special stuff that is built to handle this kind of thing, but it will kill you on platforms that might be running a "lite" version of .NET with a non-generational GC.

As always, however, profiling will tell you the real story - and will prevent you from spending a lot of time on something for no gain.

But if you're doing it for fun/learning, then go wild smile.png

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this