2012-08-15 37 views
1

對象memory有簽名的方法爲什麼要存儲一個引用而不是兩次請求我的應用程序太慢?

BinaryPattern const& getPattern(unsigned int index) const; 

我在使用這個下面的for循環:

for (unsigned int k = 0; k < memory->size(); k++) { 
    const BinaryPattern s = memory->getPattern(k); 
    w += s.at(i) * s.at(j); 
} 

這是非常緩慢的。出人意料的是,我發現下面的速度要快得多:

for (unsigned int k = 0; k < memory->size(); k++) { 
    w += memory->getPattern(k).at(i) * memory->getPattern(k).at(j); 
} 

「getPattern()」沒有做任何的計算,它非常簡單,只是返回存儲在向量模式。

爲什麼當我將參考存儲在一個變量中時速度太慢了?我最初這樣做是爲了加快速度,因爲我預計兩次檢索參考速度會更慢。

+1

將其更改爲'常量BinaryPattern&S =內存 - > getPattern(K);' – 2012-08-15 13:27:10

+0

@sbi:我錯了有關的具體細節(我不知道很多關於C++ )。我指的是複製構造函數http://en.wikipedia.org/wiki/Copy_constructor,你在你的答案中已經解釋過。 – nhahtdh 2012-08-15 13:36:10

回答

9

這是因爲

const BinaryPattern s = memory->getPattern(k); 

使對象的副本,通過調用它的拷貝構造函數。既然你不想改變它,存儲參考,而不是:

const BinaryPattern& s = memory->getPattern(k); 
//    ^
//     note this 

(由於拍攝右值與const參考直到參考死亡延長了右值的一生中,這甚至工程應的getPattern()簽名永遠改爲返回副本,而不是一個參考。)


在一個優化的版本(你沒有比較調試版本,是不是?),編譯器可能能夠確定的是,兩次調用功能

memory->getPattern(k).at(i) * memory->getPattern(k).at(j) 

沒有任何副作用,因此保留對第一個呼叫獲得的對象的引用,並優化掉第二個呼叫 - 到達上面提出的代碼。

顯然,複製BinaryPattern對象的代價是不可忽略的。

+0

啊,謝謝!我一直認爲返回一個const引用足以使變量成爲一個引用而不是副本。 – Niko 2012-08-15 13:32:29

+3

@Niko:代碼中的變量's'是一個對象,而不是一個引用。它的初始化對此沒有影響。 – sbi 2012-08-15 13:33:20

3

因爲你在這裏創造一個副本

const BinaryPattern s = memory->getPattern(k); 

只是改變

const BinaryPattern &s = memory->getPattern(k); 
+0

'+ 1',因爲你是對的 - 雖然晚了幾秒。 ':'' – sbi 2012-08-15 13:35:11

3

在行

const BinaryPattern s = memory->getPattern(k); 

創建的BinaryPattern一個新實例,並返回值getPattern被複制到它。

你可能是指

const BinaryPattern& s = memory->getPattern(k); 
+0

'+ 1'因爲你是對的 - 雖然晚了幾秒鐘。 ':)' – sbi 2012-08-15 13:34:46

相關問題