首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >shrink_to_fit是否是将容量降为“`std::vector`”的适当方法?

shrink_to_fit是否是将容量降为“`std::vector`”的适当方法?
EN

Stack Overflow用户
提问于 2014-05-06 10:31:39
回答 3查看 19.9K关注 0票数 31

在C++11中引入了shrink_to_fit来补充特定的STL容器(如std::vectorstd::dequestd::string)。

摘要,它的主要功能是请求与相关联的容器,以减少其适应其大小的容量。但是,这个请求是非绑定的,容器实现可以自由地进行优化,并使向量的容量大于其大小。

此外,在前面的一个这样的问题中,OP被禁止使用shrink_to_fit来将他的std::vector的容量减少到它的大小。不这样做的理由如下:

shrink_to_fit什么也不做,或者它会给您提供缓存位置问题,执行它是O(n) (因为您必须将每一项复制到它们的新的、较小的家园)。通常来说,留下记忆中的空白会更便宜。https://stackoverflow.com/users/80754/massa

有人能回答以下问题吗?

  • 引文中的论点成立吗?
  • 如果是,那么将STL容器的容量缩小到其大小的正确方法是什么(至少对于std::vector是这样)。
  • 如果有更好的方法收缩容器,那么shrink_to_fit存在的原因到底是什么呢?
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-06 12:07:10

引文中的论点成立吗?

量一量,你就会知道。你的记忆受到限制了吗?你能事先算出正确的尺寸吗?它对reserve的效率将比事实发生后的收缩更有效。一般来说,我倾向于同意的前提是,大多数的使用可能是好的松懈。

如果是,那么将STL容器的容量缩小到其大小的正确方法是什么(至少对于std::vector)。

这个注释不仅适用于shrink_to_fit,也适用于任何其他缩小方式。考虑到您不能将realloc放在适当的位置,它涉及到获取不同的内存块并在那里进行复制,而不管您使用何种机制进行收缩。

如果有更好的方法收缩容器,那么shrink_to_fit存在的原因到底是什么呢?

请求是不具约束力的,但是替代方案没有更好的保证。问题是收缩是否有意义:如果有,那么提供一个shrink_to_fit操作是有意义的,它可以利用对象被移动到一个新位置的事实。也就是说,如果类型T有一个noexcept(true)移动构造函数,它将分配新内存并移动元素。

虽然您可以在外部实现相同的操作,但是这个接口简化了操作。与shrink_to_fit在C++03中的相同之处是:

代码语言:javascript
运行
AI代码解释
复制
std::vector<T>(current).swap(current);

但是,这种方法的问题是,当对临时副本进行复制时,它不知道current将被替换,没有任何东西可以告诉库它可以移动所保存的对象。注意,使用std::move(current)并不能达到预期的效果,因为它会移动整个缓冲区,维护相同的capacity()

在外部实现这一点要麻烦得多:

代码语言:javascript
运行
AI代码解释
复制
{
   std::vector<T> copy;
   if (noexcept(T(std::move(declval<T>())))) {
      copy.assign(std::make_move_iterator(current.begin()),
                  std::make_move_iterator(current.end()));
   } else {
      copy.assign(current.begin(), current.end());
   }
   copy.swap(current);
}

假设我的条件是正确的..。这可能不是每次你想要这个操作时都要写的东西。

票数 18
EN

Stack Overflow用户

发布于 2014-05-07 01:26:51

  • 这些争论会站得住脚吗?

由于这些论点本来是我的,所以我可以一个接一个地为它们辩护:

  1. 要么shrink_to_fit什么也不做(.) 如前所述,标准规定(很多次,但就vector而言,它是23.3.7.3节.)该请求是非绑定的,以允许优化的实现空间。这意味着实现可以将shrink_to_fit定义为无操作。
  2. (...)或者,它会给您提供缓存位置问题。 如果shrink_to_fit不是作为非op实现的,那么您必须分配一个新的底层容器,其中包含容量size(),复制(或者,在最好的情况下,移动)从旧的项目构造所有的N = size()新项目,销毁所有旧的项目(在移动的情况下,这应该进行优化,但这可能会再次涉及旧容器上的循环),然后再对旧容器本身进行销毁。这是在libstdc++-4.9中完成的,就像大卫罗德里格斯描述的那样, _Tp(__make_move_if_noexcept_iterator(__c.begin()),__make_move_if_noexcept_iterator(__c.end()),__c.get_allocator().swap(__c); 在libc++-3.5中,由__alloc_traits中的一个函数执行大致相同的操作。 哦,一个实现绝对不能依赖于realloc (即使它在::operator new中使用malloc进行内存分配),因为如果realloc不能缩小内存(没有操作),或者按位复制(并且错过了适当的C++复制/移动构造函数所提供的重新调整指针的机会)。 当然,我们可以编写一个收缩内存分配器,并在其向量的构造函数中使用它。 在向量大于缓存线的简单情况下,所有这些移动都会给缓存带来压力。
  3. 是O(n) 如果是n = size(),我认为这是建立在上面的,至少,您必须执行一个n大小的分配、n复制或移动构造、n破坏和一个old_capacity大小的去分配。
  4. 通常情况下,只留下记忆中的空白会更便宜 显然,除非您真的需要空闲内存(在这种情况下,将数据保存到磁盘并在需要时重新加载它可能更明智.)

  • 如果是,那么将STL容器的容量缩小到其大小的正确方法是什么(至少对于std::vector)。

正确的方法仍然是shrink_to_fit..。你只需要要么不依赖它,要么非常清楚你的实现!

  • 如果有更好的方法收缩容器,那么shrink_to_fit存在的原因到底是什么呢?

没有更好的方法,但是shrink_to_fit存在的原因是,有时候你的程序可能会感觉到记忆压力,这是治疗它的一种方法。不是很好的方法,但还是。

哈哈!

票数 17
EN

Stack Overflow用户

发布于 2016-09-12 13:42:53

  • 如果是,那么将STL容器的容量缩小到其大小的正确方法是什么(至少对于std::vector)。

“交换技巧”将将向量调整到所需的精确大小(来自更有效的STL):

代码语言:javascript
运行
AI代码解释
复制
vector<Person>(persons).swap(persons);

当向量为空时,释放所有内存尤其有用:

代码语言:javascript
运行
AI代码解释
复制
vector<Person>().swap(persons);

由于保留未使用空间的分配,向量不断地绊倒了我的单元测试人员的内存泄漏检测代码,这就完美地解决了它们。

这是一个我并不关心运行时效率(大小或速度)的例子,但我确实关心内存的精确使用。

  • 如果有更好的方法收缩容器,那么shrink_to_fit存在的原因到底是什么呢?

我真的不知道提供一个合法的功能的意义是什么。当我看到它被介绍时,我欢呼起来,当我发现它不能被信赖时,我就绝望了。

也许我们会在下一个版本中看到maybe_sort()。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23502291

复制
相关文章
使枚举类型的选项在VS的属性窗里显示为中文
我们自己做的组件,一般希望它的属性在设计时能够在属性窗里显示为中文,可以在属性上添加System.ComponentModel.DisplayNameAttribute标注达到这个目的。但是,枚举的选项如何以中文的形式显示在属性窗里呢?
明年我18
2019/09/18
1.2K0
使枚举类型的选项在VS的属性窗里显示为中文
javascript表单提交的内容显示在表格中
实现三个文本域的内容提交之后显示在表格中,代码直接用文本文件运行,记得后缀改为.html 运行结果
别团等shy哥发育
2023/02/27
7.8K0
javascript表单提交的内容显示在表格中
R语言提取PDF文件中的文本内容
综上步骤,我们便可以随便获取任意章节的任意内容。那么接下来就是对这些文字的应用,各位集思广益吧。
一粒沙
2019/07/31
9.9K1
如何使特定的数据高亮显示?
当表格里数据比较多时,很多时候我们为了便于观察数据,会特意把符合某些特征的数据行高亮显示出来。这不,公司的HR小姐姐就有这个需求,说她手头上有一份招聘数据,她想把“薪水”超过20000的行突出显示出来,应该怎么操作呢?
猴子聊数据分析
2020/02/26
5.8K0
R中的向量化运算
1、R中的向量化运算-seq seq(1, 10, by=1) seq(1, 10, by=0.1) seq(1.9, 10, by=0.1) #注意,不能这样子递减 seq(10, 1, by=0.1) #注意,你可以这样子递减 seq(10, 1, by=-0.1) #除了设置步长,还可以设置均分的步数 seq(10, 1, length.out=10) seq(10, 1, length.out=100) seq(10, 1, length.out=91) #数清楚里面的个数 2、R中
Erin
2018/01/09
2K0
"0.1"在PL/SQL Developer和sqlplus中如何不显示为".1"?
微信群有朋友问,PL/SQL Developer显示0.1的时候自动将0删除,即".1",因此有什么方法,可以显示小数点之前的0?
bisal
2019/01/30
2.1K0
在 Linux 中如何按名称和 Grep 内容查找文件?
如果您使用该find命令递归搜索某些文件,然后将结果通过管道传递给该grep命令,那么您实际上将解析文件路径/名称,而不是它们的内容。
网络技术联盟站
2022/05/11
6.8K0
在 Linux 中如何按名称和 Grep 内容查找文件?
cat命令 – 在终端设备上显示文件内容
Linux系统中有很多个用于查看文件内容的命令,每个命令又都有自己的特点,比如这个cat命令就是用于查看内容较少的纯文本文件的。cat这个命令也很好记,因为cat在英语中是“猫”的意思,小猫咪是不是给您一种娇小、可爱的感觉呢?
用户4988085
2021/07/24
1.7K0
MATLAB中向量_向量法表示字符串
matlab中的向量是只有一行元素的数组,向量中的单个项通常称为元素。Matlab中的向量索引值从1开始,而不是从0开始。
全栈程序员站长
2022/11/17
2.4K0
MATLAB中向量_向量法表示字符串
linux 查看文件内容 显示行号
linux 系统中文件内容显示行号分为临时显示和永久显示两种,本文对两种方式进行介绍
全栈程序员站长
2022/06/25
15.1K0
linux 查看文件内容 显示行号
Python把PDF文件中每页内容分离为独立图片文件
封面图片:《Python程序设计实验指导书》(ISBN:9787302525790),董付国,清华大学出版社
Python小屋屋主
2019/07/23
1.5K0
Python把PDF文件中每页内容分离为独立图片文件
每日一题--4--在两个文件中取交集,显示指定的内容
把这个两个文件都存在的用户的密码输出出来 [root@sentinel student]# head file1 file2 ==> file1 <== oldboy 1234 alex 4567 lidao 9999 ==> file2 <== 001 lidao 002 alex 003 oldboy 004 oldgirl 提示:需要用到如何判断这两个文件不是一个文件。 解题思路 awk 'FNR==NR{h[$1]=$2}FNR!=NR{print h[$2]}' file1 fi
张琳兮
2019/03/14
1.3K0
在DragonOS中,使蜂鸣器发声
很简单,代码如下: void beep(uint64_t times) { io_out8(0x43, 182&0xff); io_out8(0x42, 2280&0xff); io_out8(0x42, (2280>>8)&0xff); uint32_t x = io_in8(0x61)&0xff; x |= 3; io_out8(0x61, x&0xff); times *= 10000; for(uint64_t i=0;i<times
灯珑LoGin
2022/10/31
4250
转义字符'\r'在Python内置函数print()中的妙用
在Python 3.x中,内置函数print()用来实现格式化输出,各参数含义请参考本文末尾的相关阅读。本文重点介绍print()函数的end参数以及转义字符'\r'的妙用。 本文末尾的相关阅读中已经
Python小屋屋主
2018/04/16
4.2K0
转义字符'\r'在Python内置函数print()中的妙用
如何将文件内容转成String字符串
以上两种方式从编码简洁度来讲,肯定是第二种好很多,但其实性能是差不多的,一个是牺牲了读的性能,另一个是牺牲了写的性能。
Java深度编程
2020/06/10
3.6K0
R沟通|​在Rstudio中运行tex文件
这期主要介绍下如何在Rstudio中运行和使用.tex文件,并给大家安利一个非常nice的模板和根据该模板制作的案例。
庄闪闪
2021/04/09
3.9K0
如何使用EvilTree在文件中搜索正则或关键字匹配的内容
 关于EvilTree  EvilTree是一款功能强大的文件内容搜索工具,该工具基于经典的“tree”命令实现其功能,本质上来说它就是“tree”命令的一个独立Python 3重制版。但EvilTree还增加了在文件中搜索用户提供的关键字或正则表达式的额外功能,而且还支持突出高亮显示包含匹配项的关键字/内容。  工具特性  1、当在嵌套目录结构的文件中搜索敏感信息时,能够可视化哪些文件包含用户提供的关键字/正则表达式模式以及这些文件在文件夹层次结构中的位置,这是EvilTree的一个非常显著的优势;
FB客服
2023/03/29
4.1K0
如何使用EvilTree在文件中搜索正则或关键字匹配的内容
获取类路径某个json文件中的内容字符串
实际项目中可能会有需要读取类路径下面的配置文件中的内容的需求,由于springboot项目打包的是jar包,通过文件读取获取流的方式开发的时候没有问题,但是上到linux服务器上就有问题了,对于这个问题记录一下处理的方式
在水一方
2022/09/16
2.7K0
点击加载更多

相似问题

SQL update语句为表记录的每个不同子集填充数值序列

31

SQL update语句不更改记录

11

如何编写update SQL语句以更新多条记录

23

MS SQL update语句使用逗号分隔值

216

原始SQL update语句,而date值设置为NULL

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档