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.
Related
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)
I want to process many integers in a class, so I listed them into an int* array.
int*[] pp = new int*[]{&aaa,&bbb,&ccc};
However, the compiler declined the code above with the following EXCUSE:
> You can only take the address of an unfixed expression inside of a fixed statement initializer
I know I can change the code above to avoid this error; however, we need to consider ddd and eee will join the array in the future.
public enum E {
aaa,
bbb,
ccc,
_count
}
for(int i=0;i<(int)E._count;i++)
gg[(int)E.bbb]
Dictionary<string,int>ppp=new Dictionary<string,int>();
ppp["aaa"]=ppp.Count;
ppp["bbb"]=ppp.Count;
ppp["ccc"]=ppp.Count;
gg[ppp["bbb"]]
These solution works, but they make the code and the execution time longer.
I also expect a nonofficial patch to the compiler or a new nonofficial C# compiler, but I have not seen an available download for many years; it seems very difficult to have one for us.
Are there better ways so that
I do not need to count the count of the array ppp.
If the code becomes long, there are only several letters longer.
The execution time does not increase much.
To add ddd and eee into the array, there are only one or two
setences for each new member.
.NET runtime is a managed execution runtime which (among other things) provides garbage collection. .NET garbage collector (GC)
not only manages the allocation and release of memory, but also transparently moves the objects around the "managed heap", blocking
the rest of your code while doing it.
It also compacts (defragments) the memory by moving longer lived objects together, and even "promoting" them into different parts of the heap, called generations, to avoid checking their status too often.
There is a bunch of memory being copied all the time without your program even realizing it. Since garbage collection is an operation that can happen at any time during the execution of your program, any pointer-related
("unsafe") operations must be done within a small scope, by telling the runtime to "pin" the objects using the fixed keyword. This prevents the GC from moving them, but only for a while.
Using pointers and unsafe code in C# is not only less safe, but also not very idiomatic for managed languages in general. If coming from a C background, you may feel like at home with these constructs, but C# has a completely different philosophy: your job as a C# programmer should be to write reliable, readable and maintenable code, and only then think about squeezing a couple of CPU cycles for performance reasons. You can use pointers from time to time in small functions, doing some very specific, time-critical code. But even then it is your duty to profile before making such optimizations. Even the most experienced programmers often fail at predicting bottlenecks before profiling.
Finally, regarding your actual code:
I don't see why you think this:
int*[] pp = new int*[] {&aaa, &bbb, &ccc};
would be any more performant than this:
int[] pp = new int[] {aaa, bbb, ccc};
On a 32-bit machine, an int and a pointer are of the same size. On a 64-bit machine, a pointer is even bigger.
Consider replacing these plain ints with a class of your own which will provide some context and additional functionality/data to each of these values. Create a new question describing the actual problem you are trying to solve (you can also use Code Review for such questions) and you will benefit from much better suggestions.
I've got a few global arrays I use in a simple WinForms game. The arrays are initialized when a new game starts. When a player is in the middle of the game (the arrays are filled with data) he clicks on the StartNewGame() button (restarts the game). What to do next?
Is it ok to reinitialize the whole array for the new game or should I just set every array item to null and use the already initialized array (which would be slower)?
I mean is it okay to do something like this?
MyClass[,] gameObjects;
public Form1()
{
StartNewGame();
// game flow .. simplified here .. normally devided in functions and events..
StartNewGame();
// other game flow
}
public StartNewGame()
{
gameObjects = new MyClass[10,10];
// some work with gameObjects
}
This almost entirely depends upon MyClass, specifically how many data members it contains, how much processing does its constructor (and members' constructors) require and whether it is a relatively simply operation to (re)set an object of this class to "initialized" state. A more objective answer can be obtained through benchmarking.
From you question, I understand that there are not so many array's - in that case I would say, reinitialize the whole array
In cases you have a lot of work that can take 30 sec to set up maybe you do clean up instead of reinitializing everything.
If you choose to place null, you can jet some ugly exception , so I think you rather clean the object inside the array rather then set them to null
If there are only 100 elements as in your example, then there shouldn't really be a noticeable performance hit.
If you reinitialize the array, you will perform n constructions for n objects. The garbage collector will come clean up the old array and de-allocate those old n objects at some later time. (So you have n allocations upfront, and n deallocations by the GC).
If you set each pointer in the array to null, the garbage collector will still do the same amount of work and come clean up those n objects at some later time. The only difference is you're not deallocating the array here, but that single deallocation is negligible.
From my point of view, the best way to achieve performance in this case is to not reallocate the objects at all, but to use the same ones. Add a valid bit to mark whether or not an object is valid (in use), and to reinitialize you simply set all the valid bits to false. In a similar fashion, programs don't go through and write 0's to all your memory when it's not in use. They just leave it as garbage and overwrite data as necessary.
But again, if your number of objects isn't going into the thousands, I'd say you really won't notice the performance hit.
gameObjects = new MyClass[10,10];
... is the way to go. This is definitely faster than looping through the array and setting the items to null. It is also simpler to code and to understand. But both variants are very fast in anyway, unless you have tens of millions of entries! '[10, 10]' is very small, so forget about performance and do what seems more appropriate and more understandable to you. A clean coding is more important than performance in most cases.
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.
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