【问题标题】:Use std::swap between vectors or vector::swap?在向量或向量::swap 之间使用 std::swap?
【发布时间】:2015-02-25 19:00:08
【问题描述】:

给定两个 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

【问题讨论】:

  • 一般性以外。
  • @DietmarKühl 是的,绝对是。我的意思是“超载”,但现在编辑我的第一条评论为时已晚。

标签: c++ c++11 vector swap


【解决方案1】:

假设一个健全的实现,这两个功能应该以相同的方式实现。所以你应该在你的代码中使用最易读的东西。

特别是,如果我们查看std::swap(vector&lt;T&gt; &amp; x, vector&lt;T&gt; &amp; y) 的描述,它的效果是x.swap(y)

【讨论】:

    【解决方案2】:

    无论如何你都应该直接使用std::swap()!相反,你应该使用这样的东西:

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

    对于std::vector&lt;...&gt;,它可能没有什么不同,因为std::vector&lt;...&gt; 显然位于命名空间std 中。否则,主要区别在于使用 std::swap() 时使用的是默认实现,而使用 ADL 概述的方法可以找到更好的版本。

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


    参考资料:

    【讨论】:

    • 感谢您的建议。这是否是 std::swap 没有使用上述示例进行优化时似乎更慢的原因?
    • @coincoin:没有优化的分析 C++ 代码是徒劳的!例如,对所有微不足道的内联内容进行函数调用会增加大量成本。由于生产代码肯定总是使用优化,因此未优化代码的性能也无关紧要。
    • 投了反对票,因为问题的实际答案只在最后一段,其余的基本上是对代码风格的评论。我也不同意第一部分,我会说如果你真的必须使用“使用”,在这种情况下它是没有必要的。
    • @DietmarKühl 您的评论根本不正确,我对调试构建进行了所有分析,我对优化正在使用的算法感兴趣,而不是删除一些产生微不足道的函数调用.
    【解决方案3】:

    来自实施文档:

    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)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-01
      • 1970-01-01
      • 2020-04-13
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多