C++ 在将较大的向量移动到较小容量的向量之前,是否可以使用reserve()来提高代码性能?

C++ 在将较大的向量移动到较小容量的向量之前,是否可以使用reserve()来提高代码性能?,c++,vector,move,C++,Vector,Move,如果这个问题不完整、不清楚或重复(这是我在这里的第一个问题),请提前道歉。在学习移动语义和为我的OOP课程做一个小项目时,我偶然发现了一个我自己无法回答的问题。据我所知,std::move()的工作原理是将l值转换为r值,但假设我们将一个包含大量元素的向量移动到第二个容量为1的向量中。我可以使用reserve()来避免 大量自动重新分配第二个向量的内存,或者使用reserve()会不会因为std::move()将r值移动到第二个向量中而没有效果?我的问题的一个简单实现可以在下面找到 #inclu

如果这个问题不完整、不清楚或重复(这是我在这里的第一个问题),请提前道歉。在学习移动语义和为我的OOP课程做一个小项目时,我偶然发现了一个我自己无法回答的问题。据我所知,std::move()的工作原理是将l值转换为r值,但假设我们将一个包含大量元素的向量移动到第二个容量为1的向量中。我可以使用reserve()来避免 大量自动重新分配第二个向量的内存,或者使用reserve()会不会因为std::move()将r值移动到第二个向量中而没有效果?我的问题的一个简单实现可以在下面找到

#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;
}
#包括
#包括
#包括
int main(){
标准::向量优先(1000000);
std::向量秒(1);
std::fill(first.begin(),first.end(),7);
第二,保留(1000000);//这是否需要??
第二个=标准::移动(第一个);
返回0;
}

请看这篇文章:

std::move()
是一种
O(1)
解决方案。当您在向量上使用ith时,移动的向量现在为空,新的向量具有moved one的所有元素。
reserve()
方法在这种情况下没有任何作用(但在其他情况下非常有用)


您可以使用
std::swap()
方法,这也是一种不需要使用
reserve()
方法的方法。

不,这是不需要的,而且几乎肯定是过早优化

一个向量实际上可以用三个指针来表示(或者两个指针和一个偏移量,或者一个指针和两个偏移量……但是这些并不常见,所以在我接下来的解释中,我将想象向量由三个指针来表示)

  • 一个指针指向它管理的内存的开始
  • 一个指针指向一个指针,该指针指向已插入的项的末尾
  • 一个指针指向它所管理的内存的末尾
  • 移动构造函数
    std::vector A=std::move(b)可以通过从
    b
    获取这三个指针来实现,将它们设置为一些易于生成的值(
    nullptr
    ,例如,作为一个哨兵值,表示“我是空的”),然后一切都可以完成

    事实上,
    gcc
    就是这样做的(以及大多数标准库实现……但我手头有
    gcc
    源代码)。看


    因此,您的
    reserve
    调用充其量是由编译器优化为no-op,最坏的情况是导致不必要的内存分配。不好

    在一个(单独的)循环中做这两件事一百万次,计时。有什么区别吗?您还可以查看生成的代码,以查看编译器在这种情况下执行的操作。
    second.reserve(1000000)将不起作用<代码>第二个=标准::移动(第一个)很可能只交换内部指针。@πάνταῥεῖ 不完全是std::swap()'将交换容器,但“std::move()”将使移动的容器为空,因此,如果两个容器中都有数据,则其中一个容器中的数据将消失实际上不会降低性能?因为它必须为即将释放的内存分配内存。@Jeysym是的,你完全正确!保留大量数据会降低性能,因此在这种情况下应该避免。但只有少数情况下“reserve()”没有用处。知道容器大小后,应使用“reserve()”来提高性能:)