当前位置: 首页 > 知识库问答 >
问题:

在向量之间使用std::swap或向量::swap?

阙沛
2023-03-14


我想知道v1.swap(v2)使用std::交换(v1, v2)有什么好处。

从性能角度来看,我已经实现了一个简单的测试代码(我不确定它是否相关):

#include <iostream>
#include <vector>
#include <random>
#include <chrono>
#include <algorithm>

#define N 100000

template<typename TimeT = std::chrono::microseconds>
struct Timer
{
    template<typename F, typename ...Args>
    static typename TimeT::rep exec(F func, Args&&... args)
    {
        auto start = std::chrono::steady_clock::now();
        func(std::forward<Args>(args)...);
        auto duration = std::chrono::duration_cast<TimeT>(std::chrono::steady_clock::now() - start);
        return duration.count();
    }
};

void test_std_swap(std::vector<double>& v1, std::vector<double>& v2)
{
    for (int i = 0; i < N; i ++)
    {
        std::swap(v1,v2);
        std::swap(v2,v1);
    }
}

void test_swap_vector(std::vector<double>& v1, std::vector<double>& v2)
{
    for (int i = 0; i < N; i ++)
    {
        v1.swap(v2);
        v2.swap(v1);
    }
}

int main()
{
    std::vector<double> A(1000);
    std::generate( A.begin(), A.end(), [&]() { return std::rand(); } );
    std::vector<double> B(1000);
    std::generate( B.begin(), B.end(), [&]() { return std::rand(); } );
    std::cout << Timer<>::exec<void(std::vector<double>& v1, std::vector<double>& v2)>(test_std_swap, A, B) << std::endl;
    std::cout << Timer<>::exec<void(std::vector<double>& v1, std::vector<double>& v2)>(test_swap_vector, A, B)  << std::endl;
    std::cout << Timer<>::exec<void(std::vector<double>& v1, std::vector<double>& v2)>(test_std_swap, A, B) << std::endl;
    std::cout << Timer<>::exec<void(std::vector<double>& v1, std::vector<double>& v2)>(test_swap_vector, A, B)  << std::endl;
}

根据输出,向量::swap似乎在没有优化的情况下更快-O0。输出为(微秒):

20292
16246
16400
13898

与-O3没有显著差异。

752
752
752
760

共有3个答案

高修伟
2023-03-14

来自实施文件:

void swap(vector& __x)

   *  This exchanges the elements between two vectors in constant time.
   *  (Three pointers, so it should be quite fast.)
   *  Note that the global std::swap() function is specialized such that
   *  std::swap(v1,v2) will feed to this function.

您可以看到,std::交换(v1, v2)只是调用v1.swap(v2)。

东门清夷
2023-03-14

在任何情况下都不应直接使用std::swap()!相反,您应该使用以下内容:

using std::swap;
swap(x, y);

std::向量

对标准向量使用交换(x,y)

参考文献:

  • “使用std::swap”如何启用ADL
  • 在类方法实现的主体中使用std::swap意味着什么
濮泳
2023-03-14

假设一个合理的实现,这两个功能的实现应该相同。因此,您应该使用代码中可读性最强的内容。

特别是,如果我们看一下std::swap(vector)的描述

 类似资料:
  • 我有一个整数向量: 考虑到将始终为偶数。 我只是想把相邻的元素转换成一对,像这样: i、 两个相邻的元件连接成一对。 我可以使用什么STL算法轻松实现这一点?有没有可能通过一些标准算法来实现这一点? 当然,我可以很容易地编写一个旧的索引for循环来实现这一点。但我想知道,使用基于范围的for循环或任何其他STL算法(如等)最简单的解决方案是什么样的。

  • 我希望编写一个模板函数来接受Eigen::vectrox*(float/int/double)和std::vector 如何声明模板?下面的方法不起作用。 其基本原理是不编写单独的函数所有不同的组合。

  • 问题内容: 您如何找到从向量a到b的正负角theta? 是的,我知道theta = arccos((ab)/(|| a || b |))。 但是,它不包含符号(即不能区分顺时针或逆时针旋转)。 我需要一些可以告诉我从a到b旋转的最小角度的东西。正号表示从+ x轴向+ y轴的旋转。相反,负号表示从+ x轴向-y轴的旋转。 问题答案: 如果您选择的数学库中有atan2()函数:

  • 矢量或者说向量,可以通过2~4个分量表示一个向量,比如通过vec3(1,0,0)表示三维空间中一个沿着x轴正方向的三维方向向量,如果你有高中数学的基础,应该对向量有一定的了解,对于三维坐标的相关几何运算也有一定的概念。 关键字 数据类型 vec2 二维向量,具有xy两个分量,分量是浮点数 vec3 三维向量 ,具有xyz三个分量,分量是浮点数 vec4 四维向量 ,具有xyzw四个分量,分量是浮点

  • 在最近的一次采访中,我建议使用向量 编码过程结束后,他们说在向量上使用pair是个好主意,并要求我详细说明我之前所说的“更重”是什么意思。不幸的是,我无法详细说明。是的,我知道我们只能在一对中输入两个值,但在一个向量中可以输入更多的值,并且当向量的大小==容量等时,该向量会自动调整大小。但是我应该如何回答他们的问题?为什么具体使用<代码>向量

  • 在什么是复制交换习惯用法中,显示了这个例子: 究竟如何启用ADL?ADL只需要一个不合格的名称。我认为的唯一好处是,由于是一个函数模板,您可以在调用中使用模板参数列表(