2017-02-14 61 views
1

用數據初始化的最快/內存有效方式 a std::vector類中的成員變量是什麼?用大數據集初始化類成員矢量的最有效方法

這是我能想出:

class LargeClass 
{ 
//lot of data, with long running constructor to initialize them 
} 

class EngineClass 
{ 

public: 
EngineClass(const vector<LargeClass>& vectorOfLargeClass) 
{ 
mVectorOfLargeClass = vectorOfLargeClass; //Here is what I was able to come up 
} 

private: 
vector<LargeClass> mVectorOfLargeClass; 

} 

int main() 
{ 
vector<LargeClass> vectorOfLargeClass; 
... 
//fill vectorOfLargeClass with a lot of data 
... 
EngineClass engine(vectorOfLargeClass); 
... 
} 

我需要EngineClass持有其在main()創建vectorOfLargeClass矢量數據的副本。

我使用C++ 11,但我對語言並不完全熟悉,也許有更好的更標準的方法來完成這樣的任務。

+1

你需要做一個*副本*或你可以*移動*你已經構建了什麼? – vu1p3n0x

+0

我其實對移動和複製感興趣。移動速度比上述副本更快嗎? – Avithohol

+1

@Avithohol根據定義,如果你移動*,沒有副本,所以..是的。沒有什麼比無限快的東西= P – WhozCraig

回答

4

你可以這樣做:

class EngineClass 
{ 
public: 
    EngineClass(vector<LargeClass> vectorOfLargeClass) : 
     mVectorOfLargeClass(std::move(vectorOfLargeClass) {} 

private: 
    vector<LargeClass> mVectorOfLargeClass; 
}; 

所以,你可以移動或複製您的載體:

EngineClass engine(vectorOfLargeClass); // copy 
EngineClass engine(std::move(vectorOfLargeClass)); // move 
+0

** swap **怎麼樣?它會比**移動**更快嗎? – Avithohol

+1

交換與移動大致相同,因爲'std :: swap'應該移動,如果它有選項 – vu1p3n0x

+1

@Avithohol不,不是很明顯。 – Yakk

1

稍微更快的方法是使用構造函數的初始化列表來初始化成員變量:

EngineClass(const vector<LargeClass>& vectorOfLargeClass) 
: mVectorOfLargeClass(vectorOfLargeClass) 
{ 
} 

一般來說,喜歡初始化在構造函數的初始化列表中的成員變量。

如果您不想複製輸入矢量,而是將其元素轉移到成員矢量中,則可以使用std::vector::swap成員函數,該成員函數超快,因爲它與指針交換等價,交換矢量之間的緩衝區:

EngineClass(vector<LargeClass>& vectorOfLargeClass) 
{ 
    mVectorOfLargeClass.swap(vectorOfLargeClass); 
} 
+1

爲什麼這個稍快? – Jonas

+1

@Jonas更快,因爲你初始化成員矢量的誕生。否則,首先調用矢量的構造函數(即正在創建成員矢量),然後調用矢量的成員賦值運算符來複制元素。這涉及更多的函數調用,使得它稍慢一點。 – 101010

+1

好點。編譯器是否可以優化第一個構造函數調用? – Jonas

6

添加移動構造函數:

EngineClass(vector<LargeClass>&& vectorOfLargeClass) : 
    mVectorOfLargeClass(std::move(vectorOfLargeClass)) 
{ 
} 

然後用它如下:

EngineClass engine(std::move(vectorOfLargeClass)); 

但這種假設vectorOfLargeClass是後std::move不再需要在main

+1

強行進入是一個有趣的選擇,但你應該證明一個理由,而不是把它留在那裏。 – Yakk

+0

我沒有在這裏得到雙引用操作符......這是否意味着指針的引用被採用並傳遞給std :: move? – Avithohol

+1

@Avith'&&'作爲一個類型修飾符意味着「右值引用」,或者「引用某些東西,你可以把它當作臨時的東西,並通過安全地移動它來竊取它的狀態。它只是一個引用,但是它可以綁定到可寫入的eay中的臨時對象,或者通過'std :: move'投射的對象看起來像一個臨時對象。瞭解C++ 11中的移動和右值。 – Yakk