c++ - 为什么 move 构造函数不更快?

标签 c++ performance move semantics move-constructor

我有一个非常简单的测试用例,其中一个Geometry类包含一个非常大的std::vector。我正在比较复制/move 构造函数的速度:

class Geometry
{
public:
    Geometry(size_t size) : m_data(size) {}

    Geometry(const Geometry& other) : m_data(other.m_data)
    { std::cout << "Copy constructor" << std::endl; }

    Geometry(Geometry&& other) noexcept : m_data(std::move(other.m_data))
    { std::cout << "Move constructor" << std::endl; }

private:
    std::vector<double> m_data;
};

int main()
{
    Geometry geometry(1000000000);

    {
        ScopedTimer scopedTimer("copy constructor");
        Geometry geometry2(geometry);
    }

    {
        ScopedTimer scopedTimer("move constructor");
        Geometry geometry2(std::move(geometry));
    }
}

我预计复制构造函数会非常慢,而 move 构造函数几乎是瞬时的,因为它只需要交换底层 vector 资源的句柄。然而,这不是我在这里观察到的(ScopedTimer 只是一个基于 std::chrono 的简单计时器,它返回其构造和销毁之间的持续时间)。这是我在发布配置中得到的输出(在调试配置中观察到类似的趋势):

Copy constructor
6832 ms copy constructor
Move constructor
2605 ms move constructor

move 构造函数大约快三倍,这更好,但不是我所期望的。为什么没有比这更快呢?我期望 move 构造函数的复杂度为 O(1)。为什么 vector 尺寸越大,需要的时间就越长?代码不需要分配任何东西等。我错过了什么吗?

最佳答案

您正在测量 vector 破坏时间。如果没有它,即使在 Debug模式下, move 构造函数也不需要时间:

#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <chrono>

class ScopedTimer
{
    std::string m_text;
    ::std::chrono::high_resolution_clock::time_point start;
    public: ScopedTimer(::std::string const & text):
    m_text{text}, start{::std::chrono::high_resolution_clock::now()} {}

    public: void Report(void)
    {
        auto const end{::std::chrono::high_resolution_clock::now()};
        ::std::cout << m_text << " " << ::std::chrono::duration_cast<::std::chrono::milliseconds>(end - start).count() << ::std::endl;
    }
};


class Geometry
{
public:
    Geometry(size_t size) : m_data(size) {}

    Geometry(const Geometry& other) : m_data(other.m_data)
    { std::cout << "Copy constructor" << std::endl; }

    Geometry(Geometry&& other) noexcept : m_data(std::move(other.m_data))
    { std::cout << "Move constructor" << std::endl; }

private:
    std::vector<double> m_data;
};

int main()
{
    Geometry geometry(1000000000);
    {
        ScopedTimer scopedTimer("copy constructor");
        {
            Geometry geometry2(geometry);
            scopedTimer.Report();
        }
        scopedTimer.Report();
    }
    {
        ScopedTimer scopedTimer("move constructor");
        {
            Geometry geometry2(std::move(geometry));
            scopedTimer.Report();
        }
        scopedTimer.Report();
    }
    return 0;
}

Copy constructor
copy constructor 5099
copy constructor 6526
Move constructor
move constructor 0
move constructor 1319

关于c++ - 为什么 move 构造函数不更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55694726/

相关文章:

model - Netlogo 中是否可以创建由补丁颜色定义的边界?

c++ - 如何编写传递可变大小的匿名 std::array 的推导指南?

c++ - adobe 的 ascii85 解码器算法在某些情况下失败

java - Spark 工作之间的巨大时间差距

Java move 具有特定文件扩展名的文件

android - 将选中的项目 move 到可展开的 ListView 中

c++ - std::chrono::system_clock::now() 无自动

c++ - 我在 C++ 中使用 boost 哈希函数将 3 个 double 组合成一个面临冲突的哈希

c# - 递归和 Rx 并行性

c - 如何提高 C 中大数据排序的执行速度