在将大小较大的向量移动到容量较小的向量之前,是否可以通过使用 reserve() 来提高代码性能?
Is it possible to improve code performance by using reserve() before moving a vector with a bigger size into a vector with a smaller capacity?
如果这个问题很不完整、不清楚或重复(这是我的第一个问题),请提前致歉。在研究移动语义和为我的 OOP 课程做一个小项目时,我偶然发现了一个我自己无法回答的问题。据我所知,std::move() 的工作原理是将 l 值转换为 r 值,但假设我们将一个包含很多元素的向量移动到容量为 1 的第二个向量中。我可以使用 reserve () 避免
由于 std::move() 将 r 值移动到第二个向量中,第二个向量的大量自动内存重新分配或者使用 reserve() 没有效果?可以在下面找到我的问题的简单实现。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> first (1000000);
std::vector<int> second (1);
std::fill(first.begin(),first.end(),7);
second.reserve(1000000);//is this needed??
second=std::move(first);
return 0;
}
请看看这个post:STL vector: Moving all elements of a vector
std::move()
是一个 O(1)
解决方案。当你在向量上使用 ith 时,被移动的向量现在是空的,而新的向量具有移动的向量的所有元素。
reserve()
方法在这种情况下不会做任何事情(但在其他情况下它非常有用)。
可以使用std::swap()
方法,这也是不需要使用reserve()
方法的方法。
不,那不是必需的,而且几乎可以肯定是过早的优化。
一个向量确实可以用 3 个指针(或两个指针和一个偏移量,或一个指针和两个偏移量......但这些并不常见,所以对于我的其余解释,我会想象向量由三个指针表示)。
- 一个指针指向它管理的内存的开始。
- 一个指针指向已插入其中的项的后一位。
- 一个指针指向它管理的内存的末尾后一位。
移动构造函数 std::vector<int> a = std::move(b);
可以通过从 b
中获取这三个指针来实现,将它们设置为一些易于制作的值(nullptr
作为标记值意味着"I'm empty",例如)然后一切都会完成。
事实上,gcc
就是这样做的(大多数标准库实现...但我手边有 gcc
源代码)。参见 here。
所以您的 reserve
调用充其量被编译器优化为空操作,最坏的情况是导致不必要的内存分配。不好!
如果这个问题很不完整、不清楚或重复(这是我的第一个问题),请提前致歉。在研究移动语义和为我的 OOP 课程做一个小项目时,我偶然发现了一个我自己无法回答的问题。据我所知,std::move() 的工作原理是将 l 值转换为 r 值,但假设我们将一个包含很多元素的向量移动到容量为 1 的第二个向量中。我可以使用 reserve () 避免 由于 std::move() 将 r 值移动到第二个向量中,第二个向量的大量自动内存重新分配或者使用 reserve() 没有效果?可以在下面找到我的问题的简单实现。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> first (1000000);
std::vector<int> second (1);
std::fill(first.begin(),first.end(),7);
second.reserve(1000000);//is this needed??
second=std::move(first);
return 0;
}
请看看这个post:STL vector: Moving all elements of a vector
std::move()
是一个 O(1)
解决方案。当你在向量上使用 ith 时,被移动的向量现在是空的,而新的向量具有移动的向量的所有元素。
reserve()
方法在这种情况下不会做任何事情(但在其他情况下它非常有用)。
可以使用std::swap()
方法,这也是不需要使用reserve()
方法的方法。
不,那不是必需的,而且几乎可以肯定是过早的优化。
一个向量确实可以用 3 个指针(或两个指针和一个偏移量,或一个指针和两个偏移量......但这些并不常见,所以对于我的其余解释,我会想象向量由三个指针表示)。
- 一个指针指向它管理的内存的开始。
- 一个指针指向已插入其中的项的后一位。
- 一个指针指向它管理的内存的末尾后一位。
移动构造函数 std::vector<int> a = std::move(b);
可以通过从 b
中获取这三个指针来实现,将它们设置为一些易于制作的值(nullptr
作为标记值意味着"I'm empty",例如)然后一切都会完成。
事实上,gcc
就是这样做的(大多数标准库实现...但我手边有 gcc
源代码)。参见 here。
所以您的 reserve
调用充其量被编译器优化为空操作,最坏的情况是导致不必要的内存分配。不好!