I'm using SFML in C++ to develop a simple 2D grid visualization game engine. I have a Grid class with a std::vector<sf::Vertex> where each cell in the grid is represented by 6 vertices. When I update the color of each cell based on its state, I'm observing a massive performance difference between two loops: one using the iterator of the vector and the other using an index-based approach.
Here's where the difference appears:
inline void ChangeCellColor(Cell& cell, sf::Color color)
{
// index-based loop
auto index = cell.grid_y * width_ + cell.grid_x;
for (int i = 0; i < 6; ++i)
{
vertices_[index * 6 + i].color = color;
}
// iterator-based loop (commented out for now)
/*
auto index = cell.grid_y * width_ + cell.grid_x;
for (auto it = vertices_.begin() + index * 6; it != vertices_.begin() + index * 6 + 6; ++it)
{
it->color = color;
}
*/
}
Using the index-based loop, I achieve FPS in the range of 1150-1350. However, when I switch to the iterator-based loop, the FPS drops dramatically to 30-45.
What could be the reason behind such a drastic performance difference between the two approaches? Am I missing something about vector iterators?
Env: Visual Studio 2022, Debug build
You are most likely falling victim to Checked Iterators. These are notorious for performance issues when iterating over standard containers in Debug builds.
They can be disabled with the macro _ITERATOR_DEBUG_LEVEL. You can define this macro to expand to the value 0
in your source (before including vector
), or do it in your project settings.
I would personally define this in the project settings (C / C++ > Preprocessor > Preprocessor Definitions), but for a quickfire test you can do it directly in your source:
#define _ITERATOR_DEBUG_LEVEL 0
#include <vector>
// ...
inline void ChangeCellColor(Cell& cell, sf::Color color)
{
auto index = cell.grid_y * width_ + cell.grid_x;
for (auto it = vertices_.begin() + index * 6, end = it + 6; it != end; ++it)
{
it->color = color;
}
}
If you're using a typical Microsoft project with the precompiled header stdafx.h
, you can put it in there.