std::向量-游戏循环中的优化
std::vector - optimization during game loop
我只是对设计的优化有一些问题。
游戏中的所有游戏对象都继承自基类
class Environment;
游戏在向量上迭代,更新并渲染每个对象:
for (auto& env : this->listEnvironment)
{
if (env->GetIsMarkedForDeletion()==false)
{
env->Update();
env->Render();
}
}
只要对象没有被标记为删除即可。
所以这就是我想知道的,是创建一个单独的循环并从向量中删除所有标记为删除的对象更好,只是让它们留在向量中,不渲染它们,还是应该在渲染的同一个循环中进行?
据我所知,如果我在循环中调整向量的大小,性能会下降很多,但我可能误解了这一点。
这里有一个方法,在保持环境列表清洁方面几乎没有开销:
编辑2:可能和它的效率一样高。感谢评论中的灵感:
struct Environment {
virtual bool GetIsMarkedForDeletion() const;
virtual void Render() const;
virtual void Update();
};
struct World {
using environment_container = std::vector<std::unique_ptr<Environment>>;
environment_container listEnvironment;
static bool is_removable(const environment_container::value_type& ptr)
{
return ptr->GetIsMarkedForDeletion();
}
void do_update_and_render()
{
listEnvironment.erase(std::remove_if(begin(listEnvironment),
end(listEnvironment),
is_removable),
end(listEnvironment));
for (auto& env : this->listEnvironment)
{
env->Update();
env->Render();
}
}
};
编辑:为了回应AlchemicalApples对内存碎片的担忧,提供了版本2,除非环境的大小超过其高水位线,否则不会释放内存:
struct Environment {
virtual bool GetIsMarkedForDeletion() const;
virtual void Render() const;
virtual void Update();
};
struct World {
using environment_container = std::vector<std::unique_ptr<Environment>>;
environment_container listEnvironment;
environment_container survivingEnvironment; // = {}
void do_update_and_render()
{
if (survivingEnvironment.capacity() < listEnvironment.size()) {
survivingEnvironment.reserve(listEnvironment.size());
}
for (auto& env : this->listEnvironment)
{
if (env->GetIsMarkedForDeletion()==false)
{
env->Update();
env->Render();
survivingEnvironment.push_back(move(env));
}
}
survivingEnvironment.swap(listEnvironment);
survivingEnvironment.clear(); // note-does not clear memory so fragmentation is prevented
}
};
原件在这里进行比较:
struct Environment {
virtual bool GetIsMarkedForDeletion() const;
virtual void Render() const;
virtual void Update();
};
struct World {
using environment_container = std::vector<std::unique_ptr<Environment>>;
environment_container listEnvironment;
void do_update_and_render()
{
environment_container new_objects;
new_objects.reserve(listEnvironment.size());
for (auto& env : this->listEnvironment)
{
if (env->GetIsMarkedForDeletion()==false)
{
env->Update();
env->Render();
new_objects.push_back(move(env));
}
}
swap(new_objects, listEnvironment);
}
};
在没有分配潜在的大型新矢量的情况下进行更新的版本:
void do_update_and_render_in_place()
{
auto cursor = this->listEnvironment.begin();
auto sentry = this->listEnvironment.end();
while(sentry != cursor)
{
auto &element = **cursor;
if(element.GetIsMarkedForDeletion()) { break; }
element.Update();
element.Render();
++cursor;
}
if(sentry == cursor) { return; }
auto trailing = cursor; // beginning of deleted elements
++cursor;
for(; sentry != cursor; ++cursor) {
auto &element = **cursor;
if(false == element.GetIsMarkedForDeletion()) { continue; }
element.Update();
element.Render();
swap(*cursor, *trailing);
++trailing;
}
this->listEnvironment.erase(trailing, sentry);
}
相关文章:
- gcc 如何优化此循环?
- 循环比较(优化)
- 为什么 std::chrono 在测量循环和编译器优化的并行 OpenMP 的执行时间时不起作用?
- 优化在网格图中查找哈密尔循环的函数?
- 未能优化看似明显的循环不变量(但volatile限定符发挥了神奇的作用)
- 在循环条件中调用const vector size()似乎缺少优化
- GCC 优化了基于固定范围的 for 循环,就好像它具有更长的可变长度一样
- 通过循环展开和阻塞进行优化
- 为什么 CLang++ 不优化循环,而 G++ 优化循环?
- 嵌套循环 C++ 的优化
- 如何在卷积程序的 c++ 中优化嵌套循环
- G 4.8.5带负数组索引的循环优化错误
- 使用 OpenMP 优化外循环并减少
- C是否优化了循环的检查部分
- 如何分析优化的代码并加快循环
- 如何优化循环/if语句的C
- 使用for_each标准或提升工具优化循环
- 在模板专门化中优化循环和避免代码重复
- 矢量化/优化循环,用于宽寄存器(特别是Xeon Phi)的未对齐数据访问
- 使用GCC优化C/ c++循环中的嵌套if语句