2015-10-04 99 views
-1

我正在測試一個簡單的代碼的時間,我沒有看到區別。 在第一個塊中,它的作用就像只有指針被傳遞,在情況2和3中,它的作用就像通過值而不是引用來複制整個結構。 編輯::: 結構:將struct傳遞給一個函數C++(效率)

struct e{ 
    vector<int> a; 
}; 

這段代碼使用0秒:

void ola(e &a) 
{ 
    a.a[0] = 1; 
    a.a[9999] = 1; 
} 

int main() 
{ 
    e *a; 
    a->a.resize(10000000, 0); 
    a->a[0] = 2; 
    a->a[99999] = 2; 
    ola(*a); 
    cout << a->a[0] << " . " << a->a[99999] << endl; 
    letras.resize('z' - 'a' + 1); 
    string entrada; 
} 

這其中需要0.15秒:

void ola(e &a) 
{ 
    a.a[0] = 1; 
    a.a[9999] = 1; 
} 

int main() 
{ 
    e a; 
    a.a.resize(10000000, 0); 
    a.a[0] = 2; 
    a.a[99999] = 2; 
    ola(a); 
    cout << a.a[0] << " . " << a.a[99999] << endl; 
    letras.resize('z' - 'a' + 1); 
    string entrada; 
} 

但不應該有任何區別。也許是因爲在裝配有路過的時候它來複制結構的所有值,所以我嘗試這一個:

void ola(e *a) 
{ 
    a->a[0] = 1; 
    a->a[9999] = 1; 
} 

int main() 
{ 
    e a; 
    e* b; 
    a.a.resize(10000000, 0); 
    b = &a; 
    a.a[0] = 2; 
    a.a[99999] = 2; 
    ola(b); 
    cout << a.a[0] << " . " << a.a[99999] << endl; 
    letras.resize('z' - 'a' + 1); 
    string entrada; 
} 

在最後一個我只傳遞一個指針,它需要0,15sec了。爲什麼我看到這種差異?

+2

1.在第一個代碼塊中,「a」未初始化,但您將其解除引用。 2.如果你測量的東西爲0秒,你做錯了。 – MooseBoys

+0

0秒意味着它快,它說0,它可能是0.005秒,順便說一句,添加結構信息@MooseBoys –

+1

這種類型的問題的一般建議是,你應該比較你的編譯器生成的彙編程序。對於gcc,你可以使用-S編譯標誌。 – robal

回答

2

正確的主意。剖析你的代碼並測試你的假設,但要確保代碼實際上符合你的期望並且分析是準確的。

第一點:矢量並不總是通過引用傳遞。編譯器會盡其所能地通過引用,刪除或傳遞一些類似的技巧中的任何一個,因爲它的工作量較少,但如果不能,該向量將被複制。

第二點: 時間碼很棘手。在這裏覆蓋太棘手。但天真的假設幾乎總是錯誤的。一次運行是不夠的。許多跑步和統計分析往往需要這些跑步。

我將忽略這樣一個事實,即由於未初始化的指針在未定義的區域旅行時,情況1不起作用。這只是一個側面表演。

案例1:

void ola(e &a) 

a通過引用傳遞,實際上是和字面上這裏。除地址以外不會複製任何數據。

ola(*a); 

a取消引用以滿足基準的要求,所以我們正在使用在a的值。 a是一個指針的事實現在是不相關的。 ola獲取參考。

情況2:

void ola(e &a) 

相同的原型。也通過參考傳遞。除地址以外不會複製任何數據。

ola(a); 

a通過參考傳遞。

情況3:

void ola(e *a) 

通過引用傳遞再次,但此時的參考是一個指針。除地址以外不會複製任何數據。

ola(b); 

b是指向aola需要一個指針。無需工作。 a通過引用傳遞。

要通過值傳遞,OP會寫:

void ola(e a) 

可能做一個副本,如果編譯器感覺它。一個足夠智能的編譯器會注意到,ola絕對沒有副作用,副本被修改和丟棄,並編譯函數調用。這個天真的配置文件可以顯示驚人的高效性能,因爲沒有任何反應。

+0

謝謝你幫助我理解我所做的一切 –

0

在做任何有用的事情之前,第一個程序可能會崩潰。指向內存中的無效位置。它應該是:

e *a = new e(); 
a->a.resize(10000000, 0); 
+0

它沒有崩潰,它給了我一個正確的答案,但你可能是正確的,那麼,爲什麼要花費同一時間來解析結構作爲指針而不是解析它foo(struct a)?在第二種情況下,它需要更長的時間,因爲它必須複製所有元素 –

+1

不涉及複製。在所有情況下,值都是由ref或ptr傳遞的。只需要分配矢量。 –

+0

我做了一個測試解析它,沒有指針,通過值解析它,它花了相同的時間:/ –

1

在第一個塊,你正在使用的未使用之前初始化的指針(一個)。 我懷疑你在文章中忘記了部分代碼。

此外,目前還不清楚你想要做什麼,你想要做什麼?