std::stack 在不同容器上的实现有什么实际区别?

2024-01-04

当实施一个std::stack

有几个选项,例如:

   // stack with default underlying deque
   std::stack< int > intDequeStack;   

   // stack with underlying vector
   std::stack< int, std::vector< int > > intVectorStack;

   // stack with underlying list
   std::stack< int, std::list< int > > intListStack;

我从定义中获得什么优点和缺点std::stack在不同的容器上,当我从中得到的只是相同的操作“push、pop 和 top”?

换句话说:双端队列堆栈和向量堆栈以及列表堆栈之间有什么区别,为什么我要选择除双端队列以外的任何东西?


堆栈继承了底层容器的性能特征。

  • std::vector对于最大大小可能变化的堆栈来说是一个糟糕的选择。每个push堆栈上可能需要在向量中进行大量重新分配。除非明确请求,否则向量也永远不会收缩,因此如果堆栈变大然后收缩,则额外的内存将永远不会被释放(直到堆栈被销毁)。然而,向量与存储的数据之间只有一层间接关系。

    Therefore: If you know the maximum size your stack will reach and that size is relatively small, a vector that you've called reserve() on2 will likely be faster in all cases than either list or deque; it has very good data locality and one fewer levels of indirection to access an element.

  • std::list is a linked list so the stack will have two levels of indirection when popping1, and it will always use exactly how much memory it needs. There are no expensive reallocations on push, but it will have poor data locality since each node can be allocated anywhere in the heap; processing large amounts of data from the stack will not be able to effectively use the various CPU memory caches since each pop is likely to need to jump somewhere totally different in the heap.

  • std::deque通过在结构(通常是链表)中维护短数组的集合来结合两者的某些方面。因此,项目集群将具有良好的数据局部性,并且该结构可以按需增长和收缩,而不会大惊小怪,因为数组永远不会重新分配——如果需要更多空间,它会分配一个新数组并将其添加到开头/ 结构结束。它是向量和列表之间的一个很好的中间立场,这就是为什么它是默认值。


1 There is one level of indirection to the data, but in order to remove the last element, the linked list needs another indirection to the previous node to clear out the next-pointer.

2 Note that you will need to move the vector when constructing the container. Copying a vector does not necessarily preserve its capacity. For example, you could use this helper:

template <typename T>
std::stack<T, std::vector<T>> vector_stack(
    typename std::vector<T>::size_type capacity
) {
    std::vector<T> vec;
    vec.reserve(capacity);

    return std::stack<T, std::vector<T>>{std::move(vec)};
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std::stack 在不同容器上的实现有什么实际区别? 的相关文章

随机推荐

  • C#:调试器中的 comctl32.dll 版本 6

    我正在使用WindowsAPI代码包 http code msdn microsoft com WindowsAPICodePack对于任务对话框 当我尝试显示该对话框时 它说需要加载 comctl32 dll 的版本 6 所以我将版本 6
  • 无法推导具有嵌套类型的模板函数

    我正在使用 SystemC 库 它要求所有用户定义的类型都具有运算符 template
  • Eclipse - C++ hello world 项目的错误

    我使用的是 64 位 Windows 7 我已经下载了CDT Eclipse并已下载MinGW 之后 我创建了一个c hello world项目 这是代码 include
  • 亚马逊认知:未找到身份

    我正在开发经过开发人员身份验证的项目 我正在尝试使用下面的代码获取凭据 但它给了我以下错误 我已将 IdentityId 和 Token 从服务器代码手动粘贴到此代码中 Caused by com amazonaws services co
  • 点划线和虚线的绘图问题:如何修改默认线型以便更好地与矢量渲染器“画家”一起使用?

    Matlab 提供以下默认值线条样式 http www mathworks com help matlab ref linespec html Solid line default Dashed line Dotted line Dash
  • 阻止 PWA 在桌面上安装 chrome 76 提示?

    如果满足 PWA 标准 Chrome 76 在多功能框中引入了一个 安装应用程序 按钮 有没有办法阻止此按钮出现在 chrome 桌面的多功能框中 假设您想阻止默认设置以显示自定义安装横幅 在这里读 https love2dev com b
  • 如何使用通配符实例化泛型?

    让我们研究一些使用通配符的通用实例化情况 1 这段代码 List 生成以下错误 required class or interface without bounds found 2 但是这个 List gt 编译成功 3 和这个 List
  • java反编译

    当使用java反编译器 http java decompiler free fr 反编译特定的jar时 我得到了一些奇怪的代码 我无法识别是什么 有人能帮我吗 代码是这样的 Foo access 004 Foo this or this B
  • 动画 Android 环形的扫角

    尝试对 Android 环形进行动画处理 以产生与显示的图像序列类似的效果 我找到了可绘制形状的戒指
  • 我们是否必须在控制器中发布具有与 pojo 对象完全相同的字段的 json 对象?

    我是 Spring Rest 新手 在将 JSON 对象从 jquery 映射到控制器时遇到问题 我的 jquery JSON 对象缺少一些字段 这些字段存在于控制器上的 java 对象中 我是否必须创建新类来映射此类对象 或者有什么方法可
  • 带有 void 输入的 Lambda 表达式

    好吧 非常愚蠢的问题 x gt x 2 是一个 lambda 代表与委托相同的东西 int Foo x return x 2 但是 lambda 等价于什么 int Bar return 2 多谢 零 lambda 等价物是 gt 2
  • 将 Python 脚本移动到另一台计算机

    我想知道如果我编写一个使用计算机上已安装的库 例如 lxml 的 Python 脚本 并且我想将此脚本部署到另一台计算机上 我的选择是什么 当然 在另一台机器上安装 Python 是可以的 但是我是否还必须安装我在脚本中使用的所有库 或者我
  • 如何在两个值之间切换?

    我想在Python中的两个值之间切换 即0和1之间 例如 当我第一次运行某个函数时 它会生成数字 0 下一次 它会生成 1 第三次它会返回到零 依此类推 抱歉 如果这没有意义 但是有人知道如何做到这一点吗 Use itertools cyc
  • 警告:返回类型默认为“int”[-Wreturn-type]

    我是一名开始学习 C 的 Linux 用户 我正在尝试编译我输入的这个源代码 include
  • 覆盖 Liferay 启动事件

    我有一个关于 Liferay 启动事件的问题 Liferay 文档中给出 启动活动 输入扩展的逗号分隔类名列表com liferay portal struts SimpleAction 这些类将在指定事件中运行 有人可以告诉我两者之间有什
  • 数组越界,参数问题

    所以当我编译时 一切都会编译得很好 当我去运行该程序时 我收到此错误 线程 main 中的异常 java lang ArrayIndexOutOfBoundsException 0 在 ClientForNoDupCollection ma
  • 如何使用动态列取消透视 Oracle

    我需要取消透视一个我无法控制列的表 所以我需要动态获取列名称 这就是我所拥有的 CREATE TABLE test PK VARCHAR2 255 CHAR COL1 VARCHAR2 255 CHAR COL2 VARCHAR2 255
  • 使用迁移 API 时 Knex 迁移不起作用

    我是 knex 迁移的新手 在过去的 2 天里我一直在努力让它工作 但没有任何反应 我正在尝试使用以下命令以编程方式运行我的迁移knex migration object 首先使用 cli 我在迁移目录中创建一个迁移文件 这是它的内容 ex
  • 字节数组到 8 位真彩色图像

    我正在尝试从旧电脑游戏中提取一些精灵 我找到了精灵并将它们撕成灰度的单独文件 现在我正在尝试研究如何给它们上色 可执行文件或其数据文件中似乎没有任何调色板数据 再加上游戏所需的颜色深度 256 色 使我相信每个字节实际上是一个 8 位真彩色
  • std::stack 在不同容器上的实现有什么实际区别?

    当实施一个std stack 有几个选项 例如 stack with default underlying deque std stack lt int gt intDequeStack stack with underlying vect