2014-12-29 49 views
4

给定两个std :: vector v1,v2。
我想知道使用std :: swap(v1,v2)比v1.swap(v2)有什么好处。在向量或向量之间使用std :: swap :: swap?

我实现了一个简单的测试代码(我不知道这是有关)有关的性能上来看:

#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; 
} 

根据输出似乎矢量::交换似乎更快,没有优化-O0。 输出是(微秒):

20292 
16246 
16400 
13898 

并与-O3没有revelant差异。

752 
752 
752 
760 
+0

除了一般性。 –

+0

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

回答

7

你应该不会不是直接在任何情况下使用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)。为了与其他用途保持一致,我会使用上面列出的方法。

+0

谢谢你的建议。这是为什么std :: swap似乎较慢而没有上述例子的优化? – coincoin

+4

@coincoin:在没有优化的情况下分析C++代码是徒劳的!例如,具有函数调用一切内联的内容会增加显着的成本。由于生产代码总是使用优化,未优化代码的性能也是无关紧要的。 –

+10

直接使用std :: swap()有什么问题? – johnbakers

8

假设一个合理的实现,这两个函数都应该以相同的方式实现。所以你应该使用你的代码中最具可读性的东西。

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