std :: vector是否适合频繁调整大小?

时间:2012-07-11 08:04:45

标签: c++ stl vector resize code-design

我正在创造一个游戏,我有一些小“粒子”。它们的数量经常变化(每隔几秒钟),我想知道存储它们的最佳方法是什么。 std::vectorstd::deque更适合这个吗?

是否可以保留永远不会被使用的空间(在那个容器中)(我有上限)?

3 个答案:

答案 0 :(得分:7)

如果顺序无关紧要(而且我认为不重要),你可以将其替换为向量中的另一个,而不是移除粒子。

std::vector<Particle> particles;

当您在索引i处移除粒子时 - 只需用最后一个填充空白区域:

particles[i] = particles.back();
particles.pop_back();

如果使用指针向量,你可以使它更快。

答案 1 :(得分:2)

如果为矢量保留足够的空间,调整大小也不错,因为它不需要复制矢量的内容。

另一方面,出队可以比自动管理容量的载体更有效地生长,特别是在大序列中,因为避免了大量的重新分配。

答案 2 :(得分:2)

这真的取决于使用情况。如果您的矢量未分类,如果您实际上正在移除该粒子,则它具有复杂度O(n)以在矢量中找到它并且将复制整个矢量以使数据保持连续。使用双端队列,仍然需要O(n)才能找到,但删除是微不足道的。但是,如果您正在迭代

foreach (particle in particles)
{
    if(particle.update() == END_OF_LIFE)
    {
        particle.alive = false;
    }
    else
    {
        particle.draw();
    }
}

你可以做到这一点没有明显的开销,但是为了插入新的粒子,你需要遍历每个粒子来找到你可以替换的第一个“死”粒子(O(n)),或者跟踪那些信息在一个单独的std :: list。

我们需要知道有效回答的一件事 - 您是否需要索引到特定粒子(“给我列表中的第1000个粒子”)?此外,你有没有通过一些ID(“找到id = 421932的粒子”)查找?如果前者,vector在恒定时间内执行,而后者将由std :: unordered_set(hash_set的c ++ x11版本,boost pre x11中的类似选项)和std :: set的logn时间在常量时间执行。 / p>