Is shrink_to_fit the proper way of reducing the capacity a `std::vector` to its size?(shrink_to_fit 是将 `std::vector` 的容量减少到其大小的正确方法吗?)
问题描述
在 C++11 中引入 shrink_to_fit
以补充某些 STL 容器(例如,std::vector
、std::deque
、std::string
).
In C++11 shrink_to_fit
was introduce to complement certain STL containers (e.g., std::vector
, std::deque
, std::string
).
Synopsizing,其主要功能是请求关联的容器,减少其容量以适应其大小.然而,这个请求是非约束性的,容器实现可以自由地优化,否则向量的容量大于其大小.
Synopsizing, its main functionality is to request the container that is associated to, to reduce its capacity to fit its size. However, this request is non-binding, and the container implementation is free to optimize otherwise and leave the vector with a capacity greater than its size.
此外,在之前的 SO 问题中,不鼓励 OP 使用 shrink_to_fit
将他的 std::vector
的容量减少到其大小.不这样做的原因如下:
Furthermore, in a previous SO question the OP was discouraged from using shrink_to_fit
to reduce the capacity of his std::vector
to its size. The reasons not to do so are quoted below:
shrink_to_fit
什么都不做,或者它会给你缓存局部性问题,它是 O(n)执行(因为您必须将每个项目复制到他们新的、较小的家中).通常将松弛留在内存中会更便宜.@Massa
shrink_to_fit
does nothing or it gives you cache locality issues and it's O(n) to execute (since you have to copy each item to their new, smaller home). Usually it's cheaper to leave the slack in memory. @Massa
有人可以回答以下问题吗:
Could someone be so kind as to address the following questions:
- 引文中的论点是否成立?
- 如果是,将 STL 容器的容量缩小到其大小的正确方法是什么(至少对于
std::vector
). - 如果有更好的方法来缩小容器,那么
shrink_to_fit
到底存在的原因是什么?
- Do the arguments in the quotation hold?
- If yes, what's the proper way of shrinking an STL container's capacity to its size (at least for
std::vector
). - And if there's a better way to shrink a container, what's the reason for the existence of
shrink_to_fit
after-all?
推荐答案
引文中的论点成立吗?
Do the arguments in the quotation hold?
量一量你就知道了.你的内存受限吗?你能预先找出正确的尺寸吗?保留
比事后缩小更有效.总的来说,我倾向于同意这样一个前提,即大多数用途可能适用于 slack.
Measure and you will know. Are you constrained in memory? Can you figure out the correct size up front? It will be more efficient to reserve
than it will be to shrink after the fact. In general I am inclined to agree on the premise that most uses are probably fine with the slack.
如果是,将 STL 容器的容量缩小到其大小的正确方法是什么(至少对于 std::vector).
If yes, what's the proper way of shrinking an STL container's capacity to its size (at least for std::vector).
该注释不仅适用于 shrink_to_fit
,还适用于任何其他缩小方式.鉴于您无法 realloc
就地,它涉及获取不同的内存块并复制到那里,无论您使用什么机制进行收缩.
The comment does not only apply to shrink_to_fit
, but to any other way of shrinking. Given that you cannot realloc
in place, it involves acquiring a different chunk of memory and copying over there regardless of what mechanism you use for shrinking.
如果有更好的方法来缩小容器,那么shrink_to_fit 存在的原因到底是什么?
And if there's a better way to shrink a container, what's the reason for the existence of shrink_to_fit after-all?
请求不具有约束力,但替代方案没有更好的保证.问题是收缩是否有意义:如果有,那么提供一个shrink_to_fit
操作是有意义的,该操作可以利用对象正在移动到一个新的位置.即,如果 T
类型有一个 noexcept(true)
移动构造函数,它将分配新的内存并移动元素.
The request is non-binding, but the alternatives don't have better guarantees. The question is whether shrinking makes sense: if it does, then it makes sense to provide a shrink_to_fit
operation that can take advantage of the fact that the objects are being moved to a new location. I.e., if the type T
has a noexcept(true)
move constructor, it will allocate the new memory and move the elements.
虽然您可以在外部实现相同的功能,但此接口简化了操作.相当于 C++03 中的 shrink_to_fit
应该是:
While you can achieve the same externally, this interface simplifies the operation. The equivalent to shrink_to_fit
in C++03 would have been:
std::vector<T>(current).swap(current);
但是这种方法的问题在于,当对临时文件进行复制时,它不知道 current
将被替换,因此没有任何东西可以告诉库它可以移动持有的对象.请注意,使用 std::move(current)
不会达到预期的效果,因为它会移动整个缓冲区,保持相同的 capacity()
>.
But the problem with this approach is that when the copy is done to the temporary it does not know that current
is going to be replaced, there is nothing that tells the library that it can move the held objects. Note that using std::move(current)
would not achieve the desired effect as it would move the whole buffer, maintaining the same capacity()
.
在外部实现这个会有点麻烦:
Implementing this externally would be a bit more cumbersome:
{
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);
}
假设我的 if 条件正确……这可能不是您每次想要此操作时都想写的内容.
Assuming that I got the if condition right... which is probably not what you want to write every time that you want this operation.
这篇关于shrink_to_fit 是将 `std::vector` 的容量减少到其大小的正确方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:shrink_to_fit 是将 `std::vector` 的容量减少到其大小的正确方法吗?
基础教程推荐
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01