• Advertisement
Sign in to follow this  

When you know your program is horrible. LOL

This topic is 4380 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

I thought all went well, every class is encapsulated, a pretty perfect design, clear idea on how the classes interact, drawn out each class, their methods and attributes etc... then, somehow you manage to make a P4 lag playing a cut-short version of R-Type (ROFL). I think my problem lies at how I manage my particles. I have a about 100 particles popping everytime the ship explodes. The problem is I made each particle an object with attributes, which I thought was a good idea because then I can manage how each of them interact with the environment. I'm kinda stuck to the mentality that my approach is correct (hitting the big brick wall), any ideas how to go around this problem? thanks for your help in advance.

Share this post


Link to post
Share on other sites
Advertisement
What do the particles do? Do they just burst and then fade out or do they interact with things? You said they interact with the enviroment...are they colliding with things? Also how many particles are there at once?

Also whats this written in? ie is it windows GDI or what?

Share this post


Link to post
Share on other sites
I found that with particles you get a HUGE slowdown if you're creating a new particle each time you need one, then deleting it when done. Instead of this, look into a pooling system which preallocates a chunk of particles in advance, lets you obtain one via an Alloc() method and return to the pool with a Free() method. You could probably use a std::vector for this, provided you presize it ready.

Also for particles, make them as dumb as possible so that as little calculation is needed when you update them. If you need to do a bunch of complex math per particle on each update, your game will grind to a halt. You might also want to revise your rendering method for the particles; ensure that you're only trying to draw what's on screen (the same might also apply to updating - only create/update what you can see plus a 'buffer' area). Look into pointsprites instead of quads or triangles and finally, even look into some of the cool new GPU-only rendering and update methods for particles.

Share this post


Link to post
Share on other sites
I agree with Revolutional.
But it seems to me that std::list is faster than std::vector because with std::vector you address each element of the list whereas with std::list it's the whole list.

If the STL is too slow Takaloy you should consider of designing your own linked-list mechanisms :-)

Share this post


Link to post
Share on other sites
Quote:
Original post by HolyGrail
I agree with Revolutional.
But it seems to me that std::list is faster than std::vector because with std::vector you address each element of the list whereas with std::list it's the whole list.

If the STL is too slow Takaloy you should consider of designing your own linked-list mechanisms :-)


that doesnt sound right

the STL list will probably be much faster than a hand made one, not to mention less bug-riddled. i'd also guess that it certainly won't be any slower.

a vector should do fine, because this sentence
Quote:

it seems to me that std::list is faster than std::vector because with std::vector you address each element of the list whereas with std::list it's the whole list.

is meaningless to me.

Share this post


Link to post
Share on other sites
A vector is faster than a list, because std::vector has an accessing time of O(1), where list has an average accessing time of O(N).

Std::vector becomes very slow if you constantly exceed the allocated amount(std::vector is nothing but a dynamic array that's resized when it's too small), but with a proper setup, that shouldn't happen.

When it comes to deleting, list and vector should have similar performance. List will have O(N) jumps to find the item where vector will have O(N) movements after deleting an item.

Toolmaker

Share this post


Link to post
Share on other sites
it's a pretty simple particle, just some calculation to determine the speed, and direction of the particle, then it has a life-span in which it will respawn etc.. and a boolean counter to show if it's active.

I'm using c# & openGL.

The problem is each particle is an object, while I've never literally create/destroy, I simply 'hide' the particles.

So I have 10 monster ships, waiting to explode -> this is where it lags for 2-3 seconds. each of the monster ships store 100 particles of explosive.

even if I collect them into the pool, it doesn't reduce the amount of 'objects' I display on the GUI.

Share this post


Link to post
Share on other sites
Each particle being an object is going to slow down performance. This is how I started out with my simple particle test program, and then switched to use a manager class and particle system class. The system class used (hate to admit it) my own linked list class to manage a fixed set of particles, but I am re-writing to use std::deque(in my defense I did tune my linked list to be almost as fast as std::list - I found std::deque to be the fastest though). It does what Evolutional recommends and preallocates the particles and I simple use a bool to control whether the system is active or not. Changing the model gave me a 3x increase in frame rate. Whilst frame rate is not a true measure of the performance, a three fold increase was certainly an indicator of something getting better :-) I would recommend you redesign it.

I used this artcile by John van der Burg as a guide to designing my particle system.

hth
F451

edit: this is only to emphasise the performance gains I saw when switching to std:: containers over homegrown routines. The bigger gain you should get is from switching off having each particle an object and using a container of particles in a system class.

here were my debug timings for allocating and deallocating 500 particles from that test program


Linked List test : 500 items
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
defining my ps3 class object (STL deque)
setting up objects for ps3class list
setup3 took 0.0293895 CPU seconds
destroying nodes and list
delete3 took 0.0318766 CPU seconds. Total CPU time = 0.0612662

defining my ps class object (STL list)
setting up objects for psclass list
setup1 took 0.0882187 CPU seconds
destroying nodes and list
delete1 took 0.109705 CPU seconds. Total CPU time = 0.197924

defining my ps class 2 object (Home Brew)
setting up objects for psclass2 list
setup2 took 0.088168 CPU seconds
destroying nodes and list
delete2 took 0.100711 CPU seconds. Total CPU time = 0.188879


[Edited by - Fahrenheit451 on January 19, 2006 11:34:55 AM]

Share this post


Link to post
Share on other sites
You can use the erase-remove idiom to sweep out all "dead" particles from the list in one pass. With a vector, this should work quite efficiently because the vector's reserved capacity will not be altered by this process (if you know the max number of particles, you could just use an array, but there really isn't a benefit there).

Beyond that, I'd have to see some code to help. (You're not by any chance doing any *logging* of the particle births/deaths? That would be horrendously slow.)

Share this post


Link to post
Share on other sites
All of the above information is useless because you don't *know* what the root cause of the slowness actually is. Run a profiler over your code and see what sticks out. If you havn't got a profiler, get one. And remember that with languages like C# and Java that run on a VM you should first perform a 'warm up' stage before actually performing your profiling (or just let the profiling run for ages, reducing initial startup to to a negilable amount of time).

Other (cruder) methods would be cutting out specific sections one at a time and comparing the result - such as running the full logic but no rendering, or vice versa.

Share this post


Link to post
Share on other sites
Quote:
Original post by OrangyTang
All of the above information is useless because you don't *know* what the root cause of the slowness actually is. Run a profiler over your code and see what sticks out. If you havn't got a profiler, get one. And remember that with languages like C# and Java that run on a VM you should first perform a 'warm up' stage before actually performing your profiling (or just let the profiling run for ages, reducing initial startup to to a negilable amount of time).

Other (cruder) methods would be cutting out specific sections one at a time and comparing the result - such as running the full logic but no rendering, or vice versa.


Thats true, but there are obvious (to us) optimisations that can occur or stand out that can be addressed before one has to engage profiling software, so I wouldn't exactly call it useless. I would call profiling (with a profiler) the second level of optimisation, not the first. We are his first level I guess. I would think most hobbyist (sp?) programmers don't use profiling software, so the advice given is very relevant - as is using a profiler of course to further tune your code :-)

F451

Share this post


Link to post
Share on other sites
Quote:
Original post by Fahrenheit451
Quote:
Original post by OrangyTang
All of the above information is useless because you don't *know* what the root cause of the slowness actually is. Run a profiler over your code and see what sticks out. If you havn't got a profiler, get one. And remember that with languages like C# and Java that run on a VM you should first perform a 'warm up' stage before actually performing your profiling (or just let the profiling run for ages, reducing initial startup to to a negilable amount of time).

Other (cruder) methods would be cutting out specific sections one at a time and comparing the result - such as running the full logic but no rendering, or vice versa.


Thats true, but there are obvious optimisations that can occur or stand out - like in this case. Creating 100 particle objects of a particle class compared to one class that contains and array or list of 100 particles. Those optimisations can occur before you begin to profile your code, so I wouldn't call it useless. I would call profiling (with a profiler) the second level of optimisation, not the first.

F451

Except that everyone's "obvious" optimisations surrounding containers and memory management has been C++ specific, where Takaloy has already said he's using C# which has rather different behaviour regarding memory allocation and containers.

Besides, if the rendering is the bottleneck then the "obvious" optimisations surrounding logic and memory aren't going to actually produce any noticable framerate improvements.

Share this post


Link to post
Share on other sites
Quote:
Original post by OrangyTang
Except that everyone's "obvious" optimisations surrounding containers and memory management has been C++ specific, where Takaloy has already said he's using C# which has rather different behaviour regarding memory allocation and containers.


ok. I overlooked that part :-) I was referring to C++. I don't know C#.

Quote:

Besides, if the rendering is the bottleneck then the "obvious" optimisations surrounding logic and memory aren't going to actually produce any noticable framerate improvements.


Not necessarily. If he's instantiating 100 objects of a particular class every time he wants to render an explosion, then offering him up an alternative approach that doesn't require that will improve rendering performance - which is the way I read his problem.

F451

Share this post


Link to post
Share on other sites
(I don't know C#, this is C++, but it still might help)

I made a simplistic partical system for explosions too, but it ran fine. What I did was have an std::list of ParticleHandlers. Each ParticleHandler had an array for 100 particles(particles where simply a struct with two ints, x and y). The ParticleHandler just looped through all of its particles and drew them onto the screen. It worked really well.

Also, when I first started using SDL, I draw everything pixel by pixel. At first, I didn't 'lock' and 'unlock' the screen, so it had to do that automatically for ever single pixel I drew. This caused a *major* slowdown. Is there anything like this in C#? If so, make sure your not doing a similiar mistake.

Share this post


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

  • Advertisement