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

Use std::swap between vectors or vector::swap?

本文关键字:swap vector std 向量 之间      更新时间:2023-10-16

给定两个std::vector v1, v2。
我想知道使用 std::swap(v1, v2) 比 v1.swap(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;
}

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

20292
16246
16400
13898

对于 -O3 来说,没有明显的区别。

752
752
752
760

假设一个健全的实现,这两个函数的实现方式应该相同。因此,您应该使用代码中最具可读性的内容。

特别是,如果我们看一下std::swap(vector<T> & x, vector<T> & y)的描述,它的效果是x.swap(y)的。

在任何情况下都

不应该直接使用std::swap()!相反,您应该使用类似以下内容:

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

对于std::vector<...>来说,它可能没有区别,因为std::vector<...>显然生活在命名空间std中。否则,主要区别在于,使用std::swap()将使用默认实现,而使用有关 ADL 概述的方法可以找到更好的版本。

swap(x, y)用于std::vector<...>xy只会调用x.swap(y)。为了与其他用途保持一致,我会使用上面列出的方法。


引用:

  • "使用 std::swap"如何启用 ADL?
  • 类方法实现主体中的"使用 std::swap"是什么意思?

来自实现文档:

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::swap(v1,v2) 只是调用 v1.swap(v2)。