2014-12-29 94 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)