2017-02-14 8 views
1

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); 
... 
} 

私はmain()で作成されたvectorOfLargeClassベクトルのデータのコピーを保持するためにEngineClassを必要としています。

私はC++ 11を使用しますが、私は言語に完全に慣れていないよ、多分、このような作業を行うためのより良い、より標準的な方法があります。

+1

必要がありますかあなたはすでに作ったものを移動することができますか? – vu1p3n0x

+0

私は実際に移動とコピーの両方に興味があります。上記のコピーよりも移動が速いですか?定義により、 – Avithohol

+1

@Avithoholは、ええ...何のコピー場合*移動*、そうはありません。何も無限に速いものはありません= P – WhozCraig

答えて

4

に必要なstd::move後です:

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

何について**スワップ**?それは**移動**より速いでしょうか? – Avithohol

+1

スワップは、 'std :: swap'がオプションである場合に移動する必要があるため、移動とほぼ同じです – vu1p3n0x

+1

@Avithoholいいえ、目立たないほどです。 – Yakk

1

Aわずかに速い方法は、あなたのメンバ変数を初期化するために、コンストラクタの初期化子リストを使用することです:

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を前提としていますが何もしなくなっmain

+1

ムーブインを強制するのは興味深いオプションですが、ただそこに置くのではなく正当化する必要があります。 – Yakk

+0

私はここでダブルリファレンス演算子を取得しない...それは、ポインタの参照が取られ、std :: moveに渡されることを意味しますか? – Avithohol

+1

@Avith '&&'は型修飾子で、 "値の参照"を意味するか、 "一時的なものとして扱い、その状態から安全に移動して状態を盗むことができるものへの参照"を意味します。単なる参考文献ですが、書き込み可能なeayの一時オブジェクトや、 'std :: move 'を介してキャストされたオブジェクトから一時的に見えるオブジェクトにバインドするものです。 C++ 11で移動と右辺値について学ぶ。 – Yakk

関連する問題