c++ - 使用 move::semantic 将大量 vector 合并为一个更大的 vector

标签 c++ c++11 vector c++14 move

我有大量对象可以序列化为 array<double, 5> ,让我们称他们为stuff , 我想将所有这些对象合并成一个大的 vector<double> , 称之为 data ,用于在离散本地/远程节点之间进行同步的消息传递。

我认为使用 move 语义将 stuff 的数据 move 到 data 应该给我带来巨大的性能提升复制数据,但在测试中,它实际上在 Debug模式下执行得相当慢,而在 Release模式下稍微慢一些。我在想是否有一种标准的方法来实现最佳性能?以下是我使用的实现:

std::vector<std::array<double, 5> > stuff(2000);
std::vector<double> data;
data.reserve(10000);

1)

for (auto & b : stuff) {
        data.insert(data.end(), std::make_move_iterator(b.begin()),
                std::make_move_iterator(b.end()));
}

2)

for (auto & b : stuff) {
    for (auto & item : b) {
        data.emplace_back(std::move(item));
    }
}

3)

for (auto & b : stuff) {
    std::move(b.begin(), b.end(), std::back_inserter(data));
}

4)

for (auto & b : stuff) {
    for (const auto & item : b) {
        data.emplace_back(item);
    }
}

附言: 我正在使用带有 -O3 -march=native -mavx 标志的 g++

最佳答案

首先,std::move 可以提高性能,但它只对拥有某种资源的复杂类型有效。看这个例子:

class MyVector {
    double* data;
    size_t size;

    ...

    MyVector(MyVector&& rhs) :
        data(rhs.data),
        size(rhs.size)
    {}

    MyVector(const MyVector& rhs) :
        data(new double[rhs.size]),
        size(rhs.size)
    {
        std::copy(rhs.data, rhs.data+size, data);
    }
    ...        
};

对于我们的 MyVector, move 操作会更快,因为可以绕过数据的分配和深拷贝,只需要一个赋值。我们不为 size 属性保存任何时间,因为它是要分配的,就像在复制构造函数中一样。 对于不包含任何资源的类型(如示例中的内存), move 语义不会提高性能。所有属性都必须写入新位置,而我们是否可以删除旧对象并不重要。

在您的情况下,您尝试 move double 值,无论您是否使用 move 语义,都必须将这些值复制到新位置。您看到性能损失的原因可能是因为您阻止编译器对数据执行单个 memcopy。执行一次内存复制操作通常比按元素复制更快。

执行复制的最快方法很可能是 std::memcpy,然后是 std::copy,它专门用于使用 std::memcpy 用于普通类型。您可能看不到速度的提高,因为编译器识别出您想要复制大量 double 并优化您的代码以无论如何使用 memcpy。如果您想了解发生了什么,可以使用 objdump 或 gdb 检查 asm 代码。

关于c++ - 使用 move::semantic 将大量 vector 合并为一个更大的 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44712555/

相关文章:

c++ - 如何找到套接字的IP地址c++/c

c++ - 在 C++ 中使用 srand()

c++ - Clang++ Xcode 4.4 非静态成员初始化和移动构造函数

c++ - Boost共享 vector 的大小不断波动

loops - vhdl比较向量输出

c - Vector 和链表 ADT 的区别

c++ - 如何定义从标准类型到用户定义类型的转换?

c++ - 这是一个好主意吗 : Class that sums pointers from a vector, 这样相等比较很快

c++ - 没有可行的 XML 解析程序重载

c++ - typedef 在具有成员用法的模板化函数上