Basically I am making a game similar to The Powder Toy. The world can have a maximum of 256,000 particles in one given frame. In my old Javascript implementation, I looped through every pixel and it caused severe lag because 256,000 is a lot to go through even when you only have around 20,000 particles active. I decided to have a container full of all the currently active particles instead, but then ran into the problem that querying a container for particles at a specific coordinate is also processor intensive. Therefore I came up at the simple solution that I should keep all particles in a lookup table (2-dimensional array) and also have a heap (array of active particles), and iterate through the heap while using the lookup table as a reference. Anything done to the heap is done to the lookup table, and vice versa. This worked very well in Javascript but now as I need to port my program to C++ I am having trouble with finding a good container to hold the heap. Vectors are very slow to add and remove and I cannot remove easily an object by reference from a vector.
Which container should I use, and if there is a better way to handle particles like those in The Powder Toy, what is it? Thanks in advance, and here is a picture for those not familiar with The Powder Toy.
Notice how each pixel there is a particle, and similar builds run extremely fast on my computer. I wonder how they do it...
Vectors are fine for this kind of problem. They provide contiguous storage, so they allow better usage of cache.
Try to allocate a proper vector capacity beforehand, either via constructor or using std::vector::reserve()
. Without this, automatic reallocation of the allocated storage space will be triggered every time your vector's size exceeds the current capacity.
You can also try removing elements from a vector using std::swap()
and then std::vector::pop_back()
, like this:
std::swap(vect.back(), vect[1]);
vect.pop_back();
instead of:
std::vector::erase()
The complexity of both std::vector::pop_back()
and std::swap()
is constant, and the complexity of std::vector::erase()
is linear.
However if you need to preserve the order of elements, the swap - pop method is of no use.