6

在编程中,我们面临需要使用中间 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++ 编译器的现状,哪种方法在时间和空间复杂度方面更好?

4

10 回答 10

15

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

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

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

默认使用第一个版本;仅当您可以给出这样做的充分理由时才使用第二个(如果原因是性能,那么您应该有证据表明好处是显着的)。

于 2008-10-19T23:39:23.200 回答
7

我说第一个更防错误。您不必记住清除它(它只会超出范围并完成)。:-)

性能方面没有太大区别,但您仍然应该衡量这两种情况并自己看看。

于 2008-10-19T23:25:13.307 回答
4

如果这是一个问题set/map/list,它不会有任何区别。如果是 的问题vector/hash_set/hash_map/string,则第二个将更快或相同的速度。当然,这种速度差异只有在您执行大量操作时才会明显(将 10,000 个整数推入vector10,000 次的速度大约是原来的两倍 - 3 秒和一些变化与 7 秒。)。

如果您正在执行诸如struct/class在数据结构中存储 a 而不是指向 a 的指针之类的操作,则这种差异会更大,因为在每次调整大小时,您都必须复制所有元素。

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

于 2008-10-19T23:24:37.177 回答
2

第二个可能在时间上稍微好一些,但差异将非常小——代码仍然必须遍历并释放集合中的每个项目,无论是重新创建还是清除它。

(在空间上它们将是相同的。)

于 2008-10-19T23:21:54.733 回答
1

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

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

于 2008-10-19T23:39:27.240 回答
1

您正在将您的集合放入堆栈,因此分配成本几乎为零!

于 2008-10-19T23:50:37.560 回答
0

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

如果您将对象插入容器中,这一点尤其明显,因为您最终可能会支付大量额外的构造/销毁成本,因为容器意识到它太小,重新分配内存,并将构造新对象复制到基于新内存的在现有对象上。

始终预分配和重用。它可以节省时间和内存。

于 2008-10-19T23:23:45.633 回答
0

几乎没有区别,尽管您的第二个避免多次调用构造函数和析构函数。另一方面,您的第一个是短行,并保证容器在循环范围之外不可见。

于 2008-10-19T23:30:46.790 回答
0

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

您可以在此处找到有关其他容器的一般讨论:重用容器 o 创建新容器

于 2013-02-28T22:15:09.157 回答
-1

我认为您可以为 STL 容器预分配一定数量的元素,因此如果您知道容器中有多少元素,那么内存分配成本就会保持不变。

于 2008-10-20T05:57:28.350 回答