if I store created sprites in a container instead of creating
From the point of view of the compileer engine engineering and analying a real 2D game (Discarding the GPU)
On a real game you'll:
- Drawing a bunch of sprites
- Apply effects and transformations to them
- Have some kind of data-persistence
So at the end you'll end up using a container!!!
Ok, how about create new:
spriteVector[ index ] = sf::Sprite() ;
spriteVector[ index ].setPosition( x , y ) ;
spriteVector[ index ].setColor( color ) ;
or reuse:
spriteVector[ index ].setPosition( x , y ) ;
spriteVector[ index ].setColor( color ) ;
You may think is cheaper to reuse, but is not:
When you reuse, you need to reset states you're not using => You end up with more memory access, so x86_64 and ARM addressing modes to write on memory you must at least use a intermediate register, popullating all the registers with the mess of reseting the state of an sprite can force the compiler to use the stack memory, stacks slots often remains in cache, in theory is faster than random heap access, but still
much slower than registers read/write.
Thats is without counting you're making it harder to debug.
Better solution:
When you'll be updating the sprite's properties linearly you can schedule them to take the best of your processor like:
sprites[ A ].setPosition( x , y ) ;
sprites[ B ].setScale( sx , sy ) ;
sprites[ C ].setRotation( rot ) ;
you can make a vector of RenderStates and draw them all together:
/*
Where:
1 -> sprites is an std::vector< sf::Sprite >
2 -> renderStates is an std::vector< sf::RenderStates >
3 -> sprite.size() == renderStates.size() is true.
4 -> sprites[ 3 ] use the render states stored in renderStates[ 3 ] ;
Hint: if the #3 is false you can use std::min() as the size count in the loop, and after the loop you put
"compensation code" if necessary.
*/
for( int i = 0 ; i < sprites.size() ; ++i )
{
window.draw( sprites[i] , renderStates[i] ) ;
}
Because internally you'll end up calling:
// taken from: RenderTarget.cpp
void RenderTarget::draw(const Vertex* vertices, std::size_t vertexCount,PrimitiveType type, const RenderStates& states);
You'll end up using likely all the data from both entities so the processor cache and pipeline is widely used, thus executing it faster.