Ahm*_*etK 1 c++ stdvector sfml c++17
我正在使用 C++ 中的 SFML 开发一个简单的 2D 网格可视化游戏引擎。我有一个带有 std::vector<sf::Vertex> 的 Grid 类,其中网格中的每个单元格由 6 个顶点表示。当我根据每个单元格的状态更新其颜色时,我观察到两个循环之间存在巨大的性能差异:一个循环使用向量的迭代器,另一个循环使用基于索引的方法。
这是差异所在:
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;
}
*/
}
Run Code Online (Sandbox Code Playgroud)
使用基于索引的循环,我实现了 1150-1350 范围内的 FPS。然而,当我切换到基于迭代器的循环时,FPS 急剧下降到 30-45。
这两种方法之间如此巨大的性能差异背后的原因可能是什么?我是否遗漏了向量迭代器的一些内容?
环境:Visual Studio 2022,调试构建
您很可能成为Checked Iterators的受害者。在调试版本中迭代标准容器时,这些因性能问题而臭名昭著。
可以使用宏_ITERATOR_DEBUG_LEVEL禁用它们。0您可以定义此宏以扩展到源中的值(在包含之前)vector(在包含 之前),或者在项目设置中执行此操作。
我个人会在项目设置中定义它(C / C++ > 预处理器 > 预处理器定义),但对于快速测试,您可以直接在源代码中执行此操作:
#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;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是带有预编译头的典型 Microsoft 项目stdafx.h,则可以将其放入其中。