How do I optimize object creation as to avoid garbage collection? - c#

I'm writing a Ray Tracer in C#. I use a Vector3 class for my points, normals, directions and colors. This class is instantiated numerous times per pixel. Is there a way I could structure my code as to avoid the massive amount of garbage collection I am seeing?

To anyone who finds this through the magic of Google. What I did was changing my Vector3 class to a Vector3 struct. This not only removed the massive GC overhead, but increased performance noticeable.

You can use Object Pool pattern to store and reuse your entities.
But i am not sure how big would be overhead in boxing/unboxing (if you use value types)

Related

Vector2 : Class or Struct?

I want a simple Vector2 class/struct with float x and y and a couple methods.
I'm still trying to wrap my head around the differences but can't quite get it yet
I know it's usually done with structs, but i want to update a large 2D array of Vector2 every frame, would that make a class better than a struct ?
First post here by the way, and thanks for all replies in advance !
would that make a class better than a struct
for this operation, neither would be specifically any better or worse; however, having a lot of long-lived objects means you're likely to hit GC glitches. The fact that it is a "large 2D array" means that you can also potentially save a significant amount of overhead (object headers) by using structs.

Game data - arrays of instances or arrays of values?

I'm making a game and need to store a fair bit of animation data. For each frame I have about 15 values to store. My initial idea was to have a list of "frame" objects that contain those values. Then I thought I could also just have separate lists for each of the values and skip the objects altogether. The data will be loaded once from an XML file when the game is started.
I'm just looking for advice here, is either approach at all better (speed, memory usage, ease of use, etc) than the other?
Sorry if this is a dumb question, still pretty new and couldn't find any info on stuff like this.
(PS: this is a 2D game with sprites, so 1 frame != 1 frame of screen time. I estimate somewhere around 500-1000 frames total)
If the animation data is not changing, you could use a struct instead of an class, which combines the "namespacing" of objects with the "value-typeness" of primitives. That will make all the values of a single frame reside in the same space, and save you some memory and page faults.
Just make sure that the size of your arrays doesn't get you into LOH if you intend to allocate and deallocate them often.
you are creating an animation So you should keep in mind a few basic things of.net:
Struct is created on stack. So, it is faster to instantiate (and destroy) a struct than a class.
On the other hand, every time you assign a structure or pass it to a function, it gets copied.
you can still pass struct by reference simply by specifying ref in the function parameter list
So it will be better to keep in mind this things

C# optimization - arrays / lists of value types and the stack (gaming)

I'm working on a game and am in the middle of a bit of AI number crunching and I want to optimize the code as much as I can. I have several structs in my code like Circle, Vector, etc. I want to reduce to a minimum the load on the GC as a result of this code since it will run many times a second and in each invocation will generate several large arrays and perform a lot of computations.
My question is, if I have a small method that can "return" multiple value types (i.e intersection of circle and vector, etc), what is the most performant way to transfer its result back to the main method?
I can think of a few ways to do it:
Return an array of the results i.e Vector[ ]
Return a List<Vector>
Pass in a List<Vector>
Any other way..?
What would be the best strategy to avoid a lot of small unnecessary objects / arrays on the heap that the GC then has to collect?
If you're in a situation where:
You're calling this method very frequently
You'll always be dealing with the same size of collection (or similar, at least)
You don't need the previous results by the time you next call it
... then you may be able to improve performance by repeatedly passing in the same array (or List<T>) and modifying it. On the other hand, you should absolutely measure performance before making any changes. You should also determine what's going to be "good enough" so you don't bend your code away from the most natural design any more than you have to.
This depends a lot of the type of your data passed, most times games use structs for vectors, intersection-data, etc...
When the data are structs you should avoid List<T> and passing per value because the data is copied then. But this depends a lot on the code, sometimes passing per value might be faster, sometimes not. I would make some performance tests. You can use this method for simple tests without a profiler:
public static Int64 MeasureTime(Action myAction)
{
var stopWatch = new Stopwatch();
stopWatch.Start();
myAction();
stopWatch.Stop();
return stopWatch.ElapsedMilliseconds;
}
When dealing with structs it might be always a good way to use out or ref.
More informations
All this situations may not cause a performance issue, they are just to explain best practices i learned when working with structs. To determine if ref and out are useful in each case you should make a performance test.
ref is used to avoid such situations:
Vector input = new Vector(x, y, z);
input = ModifyVector(input); // This line causes copies of the input vector and it's slow
The performance hit here depends a lot of the size of the Vector class, it's not a good practice to use the following method everytime. When returning a simple Int32 it's not necessary and should not be used to keep the code readable.
Right way:
Vector input = new Vector(x, y, z);
ModifyVector(ref input);
Of course the ref keyword could be used to make methods faster which return nothing, but this methods must take care about the data passed to them and should avoid modifing them. The speed benefit could be more than 50% in some situations ( I have a high-performance vector library and i tested many cases ).
out is used to avoid such situations:
Ray ray = ...;
CollisionData data = CastRay(ref ray); // Note the ref here to pass the Ray which contains 6 floats
CollisionData contains at least the point where it hits the ground and a normal. When using out here to get the result it should be much faster.
Right way:
Ray ray = ...;
CollisionData data;
CastRay(ref ray, out data);
When using arrays..
..you should know that a array is already a reference and you don't need the ref or out keyword to handle them. But when working with structs you should know that you are not holding references of the structs in your array. So when modifing a value of a array you can use ref myArray[0] to pass the value to a method and modify the struct at index zero in place without copying it. Also avoid to create new instances of them.
Don't know what is your platform/framework (XNA?), but I have encountered a problem with GC under Windows Phone 7 (7.5 got generational GC, but haven't test it). To avoid so called freezes of GC I made a collection where I pre-load all necessary data into Dictionary.
but first measure measure measure.

Small objects: create frequently or reuse?

For example, in draw method I need an instance of Rectangle to be used. Like this:
Rectangle rect = new Rectangle(FrameSize * CurrentFrame, 0, FrameSize, FrameSize);
Or other way. Define temp rectangle data member, and then use it like this:
rect.X = FrameSize * CurrentFrame;
rect.Y = 0;
rect.Width = FrameSize;
rect.Height = FrameSize;
Which way is better? One thing confuses me is that many rectangles created frequently, but many code solutions use first approach, while second one should be careful about memory consumptions.
Unless you have proved by careful measurement that reuse improves your performance you should create a new object every time.
.NET handles object creation and GC very efficient, you should not worry about any performance hit here. The second solution needs more careful coding to make sure you don't reuse objects in use somewhere else and you don't have previous state lugging around. Further more you will have more objects aging into gen1 or gen2 in the GC.
I would personally use the first approach in most cases - ideally making the type immutable if it makes sense and if the type is under your control.
The garbage collector is very good at reclaiming short-lived objects - and creating new objects means you don't need to worry about whether something still has a reference to the old object (thus making changes to it a problem).
How long lived are the objects? If they're only created locally and then used by the drawing methods, then chances are they will get collected in generation zero which is fairly efficient.
The problem with re-using a temp rectangle is that if you try to let it hang around beyond the life of a method it will be problematic for modifications in general.
As a general rule, I'd go with #1, and ONLY consider #2 if you discover later after profiling that #1 became an issue.
The former is safer when it comes to possible bugs, in respect to Rectangle class being mutable can produce some weird and hard to spot effects.
I don't think the performance penalty is serious enough to risk venturing in the wild world of mutable structs.
Consider the fact that structs are allocated on stack, in case of drawing method I personally would choose the first approach, as
Object created and initialized
Used
Pushed to GC as we leave the function.
So this is small object which is fast created and fast removed from the memory.
I would do it on an instance basis. You're not gaining much by reusing it, and it makes your code easier to break. By doing it on an instance basis, you can encapsulate some logic in a method and you won't have to worry about it breaking due to factors outside of the method.

Performance recommendations of millions objects creation

My code has to generate millions object to perform some algorithm (millions objects will be created and at the same time 2/3 of them should be destroyed).
I know that object creation causes performance problems.
Could someone recommend how to manage so huge amount of objects, garbage collection and so on?
Thank you.
Elaborating a bit on my "make them a value type" comment above.
If you have a struct Foo, then preparing for the algorithm with e.g. var storage = new Foo[1000000] will only allocate one big block of memory (I 'm assuming the required amount of contiguous memory will be available).
You can then manually manage the memory inside that block to avoid performing more memory allocations:
Keep a count of how many slots in the array are actually used
To "create" a new Foo, put it at the first unused slot and increment the counter
To "delete" a Foo, swap it with the one in last used slot and decrement the counter
Of course making an algorithm work with value types vs reference types is not as simple as changing class to struct. But if workable it will allow you to side-step all of this overhead for an one-time startup cost.
If it is possible in your algorithm then try to reuse objects - if 2/3 are destroyed immedietly then you can try to use them again.
You can implement IDisposable interface on the type whose object is been created. Then you can implment using keyword and write whatever logic involving the object within the using scope. The following links will give you a fair idea of what i am trying to say. Hope they are of some help.
http://www.codeguru.com/csharp/csharp/cs_syntax/interfaces/article.php/c8679
Am I implementing IDisposable correctly?
Regards,
Samar

Categories