浅析vector容器(3)-使用移动语义提高性能

浅析vector容器(1)-vector内存分配策略

浅析vector容器(2)-减少vector内存占用

浅析vector容器(3)-使用移动语义提高性能


在上一篇文章中,我们可知,在vector进行扩容或缩容的时候,元素的拷贝是不可避免的。既然拷贝是不可避免的,那么能不能较低拷贝的开销哪?

C++11中很大的一个特性是移动语义,移动语义可以将资源“偷”过来,避免了资源的拷贝和释放。在类有很大的资源时,使用移动语义可以大幅的提升类构造和赋值的性能。

接下来分析一下,移动语义是如何提升vector性能的。

定义一个用于测试的类

class A
{
public:
    A()
    {
        cout << "constuctor :" << this << endl;

        const char * s = "hello";
        int len = strlen(s);
        str_ = new char[len + 1];
        strcpy(str_, s);
    }

    A(const A &another)
    {
        cout << this << " cpy constructor from " << &another << endl;

        int len = strlen(another.str_);
        str_ = new char[len + 1];
        strcpy(str_, another.str_);
    }

    A(A &&another) noexcept
    {
        cout << this << " move constructor from " << &another << endl;

        this->str_ = another.str_;

        another.str_ = nullptr;
    }

    ~A()
    {
        cout << "deconstrutor :" << this << endl;
        if (str_)
        {
            delete[] str_;
        }
    }

private:
    char *str_;
};

没有移动构造时

构造vector对象
A a;
vector<A> va(3,a);

在这里插入图片描述
vector<A> va(3,a);执行完毕后,vector中有三个元素,且每个元素都有资源。
在这里插入图片描述

向vector中推入对象a
A a;
vector<A> va(3,a);

cout<<"============================"<<endl;

va.push_back(a);

在这里插入图片描述
推入a元素之前,va并没有多余的空间,所以为了存放a元素,需要再开辟一段空间,将a元素推进去,同时还需要将之前的三个元素也拷贝过去。

在拷贝之前的三个元素时,会造成资源的拷贝和释放。
在这里插入图片描述

提供移动构造时

构造vector对象
A a;
vector<A> va(3,a);

在这里插入图片描述
在这里插入图片描述

向vector中推入对象a
A a;
vector<A> va(3,a);

cout<<"============================"<<endl;

va.push_back(a);

在这里插入图片描述

可以看到,在将旧空间中的三个元素搬移到新空间时,使用的是移动构造而不是拷贝构造。在移动构造时,直接将旧元素的资源给搬移过来了,而没有发生资源的拷贝和释放。
在这里插入图片描述

vector的空间在扩容时,需要将旧空间的元素复制到新的空间,使用移动构造,可以将旧空间中,旧元素的资源给“偷”到新空间的元素中,这样就可以避免资源的拷贝和释放,可以极大的提高性能。

移动构造必须加上noexcept

A(A &&another) noexcept
{
    cout << this << " move constructor from " << &another << endl;

    this->str_ = another.str_;

    another.str_ = nullptr;
}

移动构造必须加上noexcept,否则vector不会使用移动构造,依然使用拷贝构造。

A a;
vector<A> va(3,a);

cout<<"============================"<<endl;

va.push_back(a);

在这里插入图片描述
A(A &&another)去掉noexcept后,使用的依然是拷贝构造。
在这里插入图片描述

以上截取自《C++性能优化指南》P111。

在这里插入图片描述

以上截取自《C++ primer(第五版)》P474。

docker-compose 是 Docker 官方的一个用于定义和运行容器化应用的工具。它使用 YAML 文件来配置应用的服务、网络和卷等方面的设置。 当使用 docker-compose 部署 MySQL ,可能会遇到无法访问 MySQL 的问题。出现这种情况一般有以下几个可能的原因: 1. 网络配置问题:docker-compose 在默认情况下会创建一个默认的网络,并将所有定义的服务连接到该网络。如果服务的网络配置不正确,可能导致无法访问 MySQL。可以通过检查网络配置或创建自定义网络来解决此问题。 2. 端口映射问题:MySQL 默认使用 3306 端口进行通信,但是在容器内部的端口与宿主机上的端口之间可能存在映射问题。可以通过检查端口映射配置或使用容器的 IP 地址来解决此问题。 3. 认证问题:MySQL 服务通常需要进行身份验证才能访问。在 docker-compose 文件中,可以通过设置环境变量来指定 MySQL 的用户名和密码。如果未正确设置这些环境变量,可能导致无法访问 MySQL。可以检查环境变量配置或者在容器内部手动配置用户名和密码来解决此问题。 4. 容器启动顺序问题:如果在 docker-compose 文件中定义了多个服务,并且它们之间有依赖关系,那么容器启动的顺序可能会影响 MySQL 的访问。可以通过在容器之间添加依赖或者设置延迟启动来解决此问题。 总结起来,当 docker-compose 部署的 MySQL 无法访问,通常是由于网络配置、端口映射、认证配置或容器启动顺序等问题造成的。通过检查这些配置,并进行适当的调整或修复,通常可以解决无法访问 MySQL 的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值