【问题标题】:C++: speed of std::stack::pop() methodC++:std::stack::pop() 方法的速度
【发布时间】:2011-03-16 00:50:13
【问题描述】:

我正在为自己从 STL 编写一些容器的轻量级版本。

(我知道 STL 是由专业程序员编写的,如果认为我可以比他们写得更好,我太愚蠢或太有野心了。当我写我的列表时(仅使用我需要的方法),它工作了几次更快。所以,我认为这是个好主意。但是,无论如何。)

我对@9​​87654321@ 的速度感到失望。我看了一眼 souses,发现没有很好的算法。几乎和我一样,我想:

void pop()
{
  if(topE) // topE - top Element pointer
  {
     Element* n_t = topE->lower; // element 'under' that one
     delete topE;
     topE = n_t;
  }
}

但它的运行速度比 STL 慢很多。

erase(--end());

谁能解释一下为什么迭代器擦除更快?

【问题讨论】:

  • 列表可能是最差/最慢的容器。您为堆栈使用列表这一事实会使堆栈变得更糟,因为std::stack 没有(默认情况下)。
  • @GMan - 该死的,我没有想到 - 我不使用 std::stack 所以我忘了它默认包装了一个双端队列。好点子。
  • @GMan,好吧,如果我需要一组未排序的对象并能够遍历它们(迭代),我应该使用什么?设置?
  • @MInner: A std::vectorstd::deque?
  • @Minner : set 会更糟 :) 使用向量或双端队列。

标签: c++ performance stl stack


【解决方案1】:

标准库stack 的性能有点难说,因为它是一个容器适配器,本身不是容器。所有操作都通过(最多)微小的修改传递到底层容器。

虽然有几个明显的可能性。首先,您显然使用的是链表;默认情况下,std::stack 将使用向量,至少在内存可用的情况下。其次,它只是擦除项目,这会破坏对象,但不会释放底层内存。你的似乎破坏了对象删除了内存。

【讨论】:

  • 其实std::stack默认使用双端队列。
【解决方案2】:

因为delete topE

使用 STL(至少对于 SGI 实现而言),pop() 上没有自动删除。如果您已动态分配堆栈中的元素,则由您在调用 pop() 之前解除分配。

STL pop 只是将堆栈大小缩短一倍(并销毁最后一个对象 - 不一定是堆删除)。

接下来是(看起来)您正在使用链表来存储堆栈。这将比默认的 STL 容器(SGI 使用 deque)慢wayyyy,因为您将失去缓存局部性并需要为每个元素动态分配(new/delete) - 而deque 将一次动态分配堆栈的块。

你说得最好:

STL 是由专业程序员编写的,如果我认为我可以比他们写得更好,我太愚蠢或太有野心了

至少现在是这样 :) 试试看你有多接近!

【讨论】:

  • @Charles:那里调用了对象的析构函数。 delete 没有被调用,因为对象没有作为指针存储在 STL 容器中。
  • @Charles Bailey - 如果您要存储指针,它不会被删除。 Destroy 将调用对象的析构函数——不一定是堆删除。我的编辑是否使这一点更加清晰?
  • 我没有发现一些事情:1.'按指针删除'(从堆中)和销毁对象有什么区别? 2. 我一直在尝试了解 deque 的工作原理,但只找到一个论坛帖子:cboard.cprogramming.com/cplusplus-programming/…,其中人们说 deque 是一个链表。奇怪。
  • @MInner,这两个主题本身都可能是一个问题:) 关于容器:向量是用一个动态数组实现的,当它需要增长时将被复制。这听起来很慢,但实际上它比许多小分配要快。双端队列通过存储小数组的linked_list 来改进向量。因此,您可以获得连续内存块的好处,但可以使用更小的块来扩展您的数组(在前面和后面)。
  • @MInner,关于删除与销毁。它本质上是删除分配的变量和堆栈分配的变量的销毁之间的区别。将调用析构函数,但它不涉及堆(这通常是一个较慢的操作)。用'int'想象一下:你可以int *p = new int; 然后delete p;,但是破坏int 什么都不做——非常便宜!
猜你喜欢
  • 2012-08-25
  • 2018-09-01
  • 2012-09-30
  • 2019-04-14
  • 1970-01-01
  • 2013-12-01
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多