首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用std::move是否有任何性能上的好处?

使用std::move是否有任何性能上的好处?
EN

Stack Overflow用户
提问于 2016-10-22 14:25:22
回答 3查看 5.3K关注 0票数 4

请考虑以下代码:

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <utility>

std::vector<int> vecTest;
int main() 
{
    int someRval = 3;
    vecTest.push_back(someRval);
    vecTest.push_back(std::move(someRval));
    return 0;
}

因此,据我所知,someRval的值将在push_back()的第一次调用时复制到vecTest中,但是在第二个someRval上会产生一个x值。我的问题是,会不会有任何性能上的好处,我的意思是,可能没有int,但是在处理更大的对象时,可能会有一些性能上的好处吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-22 15:02:31

移动的性能好处通常来自于动态分配被排除在外。

考虑一个过于简化(且天真)的string (缺少一个副本赋值操作符和一个移动赋值运算符):

代码语言:javascript
复制
class MyString
{
public:
    MyString() : data(nullptr) {}

    ~MyString()
    {
        delete[] data;
    }

    MyString(const MyString& other) //copy constructor
    { 
        data = new char[strlen(other.c_str()) + 1]; // another allocation
        strcpy(data, other.c_str()); // copy over the old string buffer
    }

    void set(const char* str)
    {
        char* newString = new char[strlen(str) + 1];
        strcpy(newString, str);
        delete[] data;
        data = newString;
    }

    const char* c_str() const
    {
        return data;
    }
private:
    char* data;
};

这一切都很好,但是如果字符串变长,这里的复制构造函数可能会很昂贵。但是,复制构造函数需要对所有内容进行复制,因为它不允许接触other对象,它必须按照它的名称,复制内容。如果您需要字符串的副本,这就是您必须付出的代价,但是如果您只想使用字符串的状态,并且不关心之后会发生什么,那么您最好移动它。

移动它只需要让other对象处于某种有效状态,这样我们就可以使用other中的所有东西,这正是我们想要的。现在,我们要做的不是复制我们的data指针所指向的内容,而是将我们的data指针重新分配给other中的一个,我们基本上是在窃取other的内容,我们也会做得很好,将原始的data指针设置为nullptr

代码语言:javascript
复制
MyString(MyString&& other)
{
    data = other.data;
    other.data = nullptr;
}

这就是我们要做的。这显然比复制构造函数所做的复制整个缓冲区要快得多。

示例

票数 7
EN

Stack Overflow用户

发布于 2016-10-22 14:32:56

移动“原语”类型(如int,甚至char* )与复制它们没有什么不同。

std::string这样的复杂类型可以使用您愿意牺牲源对象状态的信息,以使移动比复制更高效。

票数 4
EN

Stack Overflow用户

发布于 2016-10-22 14:36:08

是的,但这取决于应用程序的细节-对象的大小和操作的频率。

将其转换为r值并移动它(通过使用std:move())可避免复制。如果对象的大小足够大,这将节省时间(例如,考虑一个具有1000倍的数组--复制它通常意味着复制4 MB或更多的内存)。

另一点是频率--如果您的代码经常执行相应的操作,则会增加相当大的数目。

请注意,源对象在处理过程中被销毁(变得不可用),这对于您的逻辑来说可能是可以接受的,也可能是不可接受的--您需要理解它并相应地编写代码。如果您以后仍然需要源对象,那么它显然无法工作。

通常,除非您需要优化,否则不要优化。

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

https://stackoverflow.com/questions/40193269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档