C ++ STL:清理后的容器重新创建或重用?

时间:2008-10-19 23:19:00

标签: c++ stl complexity-theory

在编程中,我们面临各种需要使用中间STL容器的情况,如下例所示:

while(true)
{
    set < int > tempSet;

    for (int i = 0; i < n; i ++)
    {
        if (m.size() == min && m.size() <= max)
        {
            tempSet.insert(i);
        }
    }
    //Some condition testing code
}

或者

set < int > tempSet;

while(true)
{
    for (int i = 0; i < n; i ++)
    {
        if (m.size() == min && m.size() <= max)
        {
            tempSet.insert(i);
        }
    }
    tempSet.clear();

    //Some condition testing code
}

考虑到C ++编译器的当前状态,哪种方法在时间和空间复杂性方面更好?

10 个答案:

答案 0 :(得分:15)

第一个版本是正确的。它几乎在所有方面都比较简单。更容易编写,更易于阅读,更易于理解,更易于维护等....

第二个版本可能更快,但之后可能不会。在使用之前,您需要证明它具有显着优势。在大多数非平凡的情况下,我猜测两者之间不会有可衡量的性能差异。

有时在嵌入式编程中,避免将东西放在堆栈上会很有用;在这种情况下,第二个版本是正确的。

默认情况下使用第一个版本;只有当你能给出一个很好的理由时才使用第二个(如果原因是表现,那么你应该有证据证明这个好处很重要。)

答案 1 :(得分:7)

我说第一个更容易出错。你不必记得清除它(它只会超出范围并完成)。 : - )

在性能方面没有太大区别,但你应该测量这两种情况并亲自看看。

答案 2 :(得分:4)

如果这是set/map/list的问题,则不会有任何区别。如果它是vector/hash_set/hash_map/string的问题,则第二个将更快或相同的速度。当然,如果你进行了大量的操作,这种速度的差异将是显而易见的(10,000次推入vector 10,000次约为两倍--3秒和一些变化与7秒。 )。

如果你正在做一些事情,比如在你的数据结构中存储struct/class而不是指向一个,那么这种差异会更大,因为在每次调整大小时,你必须复制所有元素。

同样,几乎在所有情况下,都无关紧要 - 在重要的情况下,如果您正在优化,它会显示出来,并且您关心每一点性能。

答案 3 :(得分:2)

第二个可能稍微好一点,但差异将极小 - 代码仍然必须通过并释放集合中的每个项目,无论它是重新创建还是清除它

(在空间方面,他们将是相同的。)

答案 4 :(得分:1)

两者之间的性能差异很小。您应该根据代码可读性和稳健性做出决定。

我认为第一个例子更具可读性和安全性 - 当你在循环中添加条件时,六个月内会发生什么,也许在某处有一个继续 - 在第二个例子中,它将绕过clear(),你会有一个错误。

答案 5 :(得分:1)

你把你的设置放在堆栈上,因此分配成本几乎为零!

答案 6 :(得分:0)

作为一般规则,将数据加载到容器中会产生内存分配成本。通过重新使用容器避免多次支付该成本要好得多。如果您确实知道有多少项,或者可以做出好的猜测,那么您应该预先在容器中预先分配空间。

特别值得注意的是,如果要将对象插入容器中,因为最终会支付大量的额外构造/销毁成本,因为容器意识到它太小,重新分配内存,并且复制构造新对象到基于现有对象的新内存。

始终预先分配和重复使用。它节省了时间和记忆。

答案 7 :(得分:0)

尽管你的第二个避免多次调用构造函数和析构函数,但差别很小。另一方面,你的第一个是短一行,并保证容器在循环范围之外不可见。

答案 8 :(得分:0)

Set通常实现为红黑树。每个节点都是单独分配的,因此设置不会从重用中受益。这就是为什么两种方法都具有几乎相同的性能。调用“tempSet.clear()”应该大约与销毁对象的时间相同。第一种方法更好,因为它具有相同的性能并遵循更安全的编程风格。

您可以在此处找到有关其他容器的一般性讨论:Reusing a container o creating a new one

答案 9 :(得分:-1)

我认为您可以为STL容器预先分配一定数量的元素,因此如果您知道容器中有多少元素,则会有一个恒定的内存分配成本。