我正在创建一个我有小“粒子”的游戏。它们的数量变化非常频繁(每隔几秒钟),我想知道存储它们的最佳方式是什么。是std::vector
还是std::deque
更好?
保留永远不会被使用的空间(在那个容器中)是否可以(我有上限)?
如果顺序无关紧要,您可以将其替换为向量中的另一个粒子,而不是删除一个粒子(我认为它不重要)
std::vector<Particle> particles;
当您删除索引处的粒子时i
- 只需用最后一个填充空白空间:
particles[i] = particles.back();
particles.pop_back();
如果使用指针向量,您可以使其更快。
如果为向量保留足够的空间,调整大小也不错,因为它不需要复制向量的内容。
另一方面,出队可以比具有自动管理容量的向量更有效地增长,特别是在大序列中,因为避免了大量的重新分配。
这真的归结为使用情况。如果您的向量未排序,如果您实际上是在移除该粒子,则在向量中找到它的复杂度为 O(n),并且整个向量将被复制,因此数据保持连续。使用双端队列,仍然需要 O(n) 才能找到,但删除是微不足道的。但是,如果您正在迭代
foreach (particle in particles)
{
if(particle.update() == END_OF_LIFE)
{
particle.alive = false;
}
else
{
particle.draw();
}
}
您可以在没有显着开销的情况下做到这一点,但是要插入新粒子,您需要遍历每个粒子以找到第一个可以替换的“死”粒子(O(n)),或者在单独的标准::列表。
我们需要知道一件事才能有效地回答——你是否需要索引到一个特定的粒子(“给我列表中的第 1000 个粒子”)?另外,您是否曾经通过某个 ID 查找(“查找 id=421932 的粒子”)?如果是前者,vector 会在恒定时间内执行,而后者将由 std::unordered_set(c++ x11 版本的 hash_set,boost pre x11 中的类似选项)在恒定时间内执行,而 logn 时间由 std::set 执行。