2012-05-19 68 views
3

我有以下問題。我嘗試按值分配,並參考和指定here賦值ba值應該更快,雖然當我嘗試我的代碼時,它給了我一個相當混合的結果,因爲有時assign1更快,有時assign2。速度參考值與價值

class MyAddress{ 
    char *name; 
    long int number; 
    char *street; 
    char *town; 
    char state[2]; 
    long zip; 
    std::vector<int> v_int; 
public: 
    MyAddress(int i){ 
     v_int.resize(1000000); 
     std::fill(v_int.begin(),v_int.end(),i); 
    } 
    MyAddress& assign1(MyAddress const& x) 
    { 
     MyAddress tmp(x);   // copy construction of tmp does the hard work 
     std::swap(*this, tmp); // trade our resources for tmp's 
     return *this;  // our (old) resources get destroyed with tmp 
    } 
    MyAddress& assign2(MyAddress x)//x is a copy of the source; hard work already done 
    { 
     std::swap(*this, x); // trade our resources for x's 
     return *this;  // our (old) resources get destroyed with x 
    } 
}; 

主:

for(int i=0;i<10;i++){ 
     { 
      MyAddress a1(1); 
      MyAddress a2(2); 
      MyAddress a3(3); 
      clock_t tstart=std::clock(); 
      a1.assign1(a2); 
      a1.assign1(a3); 
      clock_t tend=std::clock(); 
      float time_elapsed=((float)tend-(float)tstart); 
      std::cout<<std::fixed<<"\nassign1 time elapsed : "<<time_elapsed/CLOCKS_PER_SEC; 
     } 
     { 
      MyAddress a1(1); 
      MyAddress a2(2); 
      MyAddress a3(3); 
      clock_t tstart=std::clock(); 
      a1.assign2(a2); 
      a1.assign2(a3); 
      clock_t tend=std::clock(); 
      float time_elapsed=((float)tend-(float)tstart); 
      std::cout<<"\nassign2 time elapsed : "<<time_elapsed/CLOCKS_PER_SEC; 
     } 
    std::cout<<std::endl; 
    } 

ASSIGN1經過的時間:0.093000 ASSIGN2經過的時間:0.094000

ASSIGN1經過的時間:0.095000 ASSIGN2經過的時間:0.092000

ASSIGN1經過的時間: 0.109000 assign2耗用時間:0.093000

ASSIGN1經過時間:0.099000 ASSIGN2經過時間:0.094000

ASSIGN1經過時間:0.099000 ASSIGN2經過時間:0.101000

ASSIGN1經過時間:0.096000 ASSIGN2經過時間:0.120000

ASSIGN1時間已用時間:0.098000 assign2已用時間:0.105000

assign1耗用時間:0.113000 ASSIGN2經過時間:0.108000

ASSIGN1經過時間:0.111000 ASSIGN2經過時間:0.103000

ASSIGN1經過時間:0.106000 ASSIGN2經過時間:0.106000

我做了一些修改測試代碼:現在我執行1000次迭代而不是10次。 結果仍然是混合的:對我來說特別奇怪的是有時第一次分配速度更快,但有時是第二次:

1) 
assign1 time elapsed : 111.228996 
assign2 time elapsed : 112.097000 
2) 
assign1 time elapsed : 127.087997 
assign2 time elapsed : 126.691002 

你如何解釋這個?對我來說,在這種情況下,看起來結果獨立於值或參考方法。


最後我用這樣的事情,因爲我覺得這是方法建議here如果我理解正確

MyAddress get_names(MyAddress& ref){return ref;} 

,現在在ASSIGN2是做這樣:

a1.assign2(get_names(a2)); 
a1.assign2(get_names(a3)); 

實際上,assign2的性能稍好一些,至少每次都是如此,不能像以前那樣互換。但這是我應該看到的差異嗎?

assign1 time elapsed : 127.087997 
assign2 time elapsed : 126.691002 

assign1 time elapsed : 137.634995 
assign2 time elapsed : 136.054993 

最後:

assign1 time elapsed : 1404.224976 
assign2 time elapsed : 1395.886963 
+0

如果您想要副本,請始終使用'assign2'版本。有時候它更可以優化。另外,你是否在做啓用優化的那個愚蠢的基準測試? –

+2

[想要速度?按價值傳遞](http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/)。 –

+0

@ cf16,你應該閱讀上面的鏈接,它可以解釋何時何地可能會更快。您可能還想看看[這裏](http://definedbehavior.blogspot.com/2011/08/value-semantics-copy-elision.html)另一種方法來描述可能發生的優化。最後,在C++ 11中,您可能希望提供* move *操作(構造函數/賦值)以避免依賴編譯器優化。 –

回答

6

你的分配函數基本上是一樣的。在其中一箇中,你自己拷貝 - 構建臨時文件,而另一個拷貝則由編譯器自動注入。

另外10對於您的測試來說不夠大。

+0

除了'assign2'可以更好地優化。 'a1.assign2(some_function())'可以避免不必要地複製參數(返回值優化,複製elision或任何你喜歡稱之爲的)。 –

+0

是@ K-ballo,這是區別 – 4pie0

1

對於一般情況下,
分配的參考應該總是通過值強於大盤分配。

原因:

  1. 分配通過引用不堆棧創建新的空間
  2. 它不必從舊變量中的值複製到新的可變

上述開銷可能對大多數節目來說微不足道。但是,常量和引用是一種通用的編程習慣。

在當前程序中,
兩種配置都會執行相同的操作。 用大量的迭代嘗試您的程序,以查看時間的差異。

+0

無關緊要。這兩個功能都做一個副本。 –

+0

通過引用分配可能會更快,但是當您創建新副本並由'swap'分配時(這應該是默認方式),因爲它是獲得強大異常安全性的最簡單習慣用法。 –