【问题标题】:What is the fastest way to swap two complex structures?交换两个复杂结构的最快方法是什么?
【发布时间】:2019-02-26 13:26:21
【问题描述】:

我需要将一个结构的值与另一个交换,并相信交换会比复制更快 - 我说得对吗?

#include <iostream>
#include <algorithm>
#include <vector>

class B
{
 public:
  int y;
  std::vector<int> z;
  B(){std::cout << "Called" << std::endl;}
 private:
 int z1;
};

int main()
{
 B b1, b2;
 b1.z.push_back(1);
 std::swap(b1,b2);
 std::cout << b2.z[0] << std::endl;
 b1.z.push_back(1);
 b2 = std::move(b1);
 std::cout << b2.z[0] << std::endl;
 b1.z.push_back(1);
 std::exchange(b1, b2);
 std::cout << b2.z[0] << std::endl;
 b1.z.push_back(1);
 b2 = std::forward<B>(b1);
 std::cout << b2.z[0] << std::endl;
}

上面的代码按预期进行了交换,但我不确定哪种方法最快。我的目标是将一个结构变量的值(如果更快,则交换)复制到另一个结构变量。在实际代码中,结构将具有复杂的用户定义类型。

我知道同样会有复制方式 - 但哪种方式最好/安全/快速复制到目的地?

我需要照顾一些操作员/构造函数来帮助它吗?

【问题讨论】:

  • 在现代 CPUS 上,除非向量类成员包含许多值,否则相对性能将更多地取决于附近的宇宙射线。
  • 如果您的对象自己管理资源(指针、网络连接等),您只需要自己实现复制和交换功能,而您的示例中不是这种情况。哪个是最快的:我想您必须针对您的特定情况对此进行基准测试,特别是因为您说实际代码使用我们不知道的“复杂用户定义类型”。 Here 您可以找到有关复制和交换功能的信息,包括自 C++11 以来可用的移动构造函数。
  • 您应该查看 std::exchange 的文档,它将 b2 的值移动到 b1 并返回 b1 的旧值,因此在 std::exchange(b1, b2) 之后使用 b2未定义的行为。
  • 用户定义类型是具有庞大数据结构的类

标签: c++ c++11


【解决方案1】:

给定

  1. 允许编译器为B 生成一个移动构造函数(研究5 的规则),这是一个成员移动构造,受as-if 规则

  2. std::move 使用移动构造函数(如果可用)

  3. std::swap 使用std::move

  4. std::vector 有一个移动构造函数

,简单地使用

std::swap(b1, b2);

非常难以击败。

【讨论】:

    【解决方案2】:

    我知道同样会有复制方式 - 但哪种方式最好/安全/快速复制到目的地?

    std::swap 实际上不会复制,只要您的类型是可移动的。最简单的形式看起来像

    template<typename T>
    void swap(T& lhs, T& rhs)
    {
        T tmp{std::move(rhs)};
        rhs = std::move(lhs);
        lhs = std::move(tmp);
    }
    

    所以,只要移动对象比复制对象更快,那么交换就会更快。如果不是,那么它们将具有相同的性能。

    【讨论】:

      猜你喜欢
      • 2011-09-03
      • 2011-04-26
      • 2010-09-07
      • 1970-01-01
      • 1970-01-01
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多