Hello i have a function that return an std::pair and is called very often.
std::pair<sf::Vector2i, sf::Vector2i>
Map::map_coord_to_chunk_coord(int x, int y) {
// Get the chunk position
int chunk_x = x / CHUNK_SIZE;
int chunk_y = y / CHUNK_SIZE;
// Get the position inside the chunk
x = x - chunk_x * CHUNK_SIZE;
y = y - chunk_y * CHUNK_SIZE;
// Return the chunk position and the position inside it
return std::pair<sf::Vector2i, sf::Vector2i>(sf::Vector2i(chunk_x,
chunk_y), sf::Vector2i(x, y));
}
Is this better to declare the pair as static so that it isn't created each time.
std::pair<sf::Vector2i, sf::Vector2i>
Map::map_coord_to_chunk_coord(int x, int y) {
static std::pair<sf::Vector2i, sf::Vector2i> coords;
// Get the chunk position
coords.first.x = x / CHUNK_SIZE;
coords.first.y = y / CHUNK_SIZE;
// Get the position inside the chunk
coords.second.x = x - coords.first.x * CHUNK_SIZE;
coords.second.y = y - coords.first.y * CHUNK_SIZE;
// Return the chunk position and the position inside it
return coords;
}
I run callgrind and it looks like this function is 3 time faster but is this a good practice ?
In general, one should avoid using static when the only goal is to save CPU cycles.
Making coords static renders your map_coord_to_chunk_coord function non-reentrant, meaning that it is no longer usable in concurrent environments without proper synchronization. This is a very high price to pay for saving a construction cost of a simple object.
For example, you should be able to optimize construction of std::pair by using make_pair:
inline std::pair<sf::Vector2i, sf::Vector2i>
Map::map_coord_to_chunk_coord(int x, int y) {
int first_x = x / CHUNK_SIZE;
int first_y = y / CHUNK_SIZE;
return std::make_pair(
sf::Vector2i(first_x, first_y)
, sf::Vector2i(x - first_x * CHUNK_SIZE, y - first_y * CHUNK_SIZE)
);
}
In certain cases the compiler can even optimize out the copying, further improving performance.
As others have pointed out you should generally avoid using local static variables in this way as it makes the code non thread safe.
Generally, the most idiomatic C++ is to rely on return-value-optimization and other compiler optimizations. I'd be surprised (and a little envious) if construction of a std::pair of sf::Vector2i was the bottleneck in your code but if this really is the critical piece of your code you could be slightly less idiomatic and pass-by-reference instead of using a return value:
void
map_coord_to_chunk_coord(int x, int y, std::pair<Vector2i, Vector2i>& chunk_coord) {
chunk_coord.first.x = x / CHUNK_SIZE;
chunk_coord.first.y = y / CHUNK_SIZE;
chunk_coord.second.x = x % CHUNK_SIZE;
chunk_coord.second.y = y % CHUNK_SIZE;
}
Then the caller can re-use a chunk_coord variable within a tight loop and you have no constructions of std::pair or sf::Vector2i.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With