私は答えを探すのにしばらく時間を費やしましたが、満足のいくものは何も見つかりませんでした。
私はプロトタイピングよりも少し多くのプロダクション関連のコーディングを行っているので、経験豊富なC++の人々がこの種の問題をどのように解決するかに興味があります。
大量のデータ、たとえば500Mbを保持するunordered_map(ハッシュマップ)を言うクラスがあるとします。そのデータのサブセットを効率的に返すアクセサーを作成する必要があります。
次のようになります。ここで、BigDataは、適度な量のデータを格納するクラスです。
Class A
{
private:
unordered_map<string, BigData> m_map; // lots of data
public:
vector<BigData> get10BestItems()
{
vector<BigData> results;
for ( ........ // iterate over m_map and add 10 best items to results
// ...
return results;
}
};
アクセサget10BestItemsは、最初にアイテムを結果ベクトルにコピーし、次に関数が返されるときに結果ベクトルがコピーされるため(関数スタックからコピー)、このコードではあまり効率的ではありません。
さまざまな理由から、c__に参照のベクトルを含めることはできません。これは明らかな答えです。
vector<BigData&> results; // vector can't contain references.
ヒープ上に結果ベクトルを作成し、その参照を渡すことができます。
vector<BigData>& get10BestItems() // returns a reference to the vector
{
vector<BigData> results = new vector<BigData>; // generate on heap
for ( ........ // iterate over m_map and add 10 best items to results
// ...
return results; // can return the reference
}
ただし、注意しないと、メモリリークの問題が発生します。また、低速(ヒープメモリ)であり、マップからベクターにデータをコピーします。
したがって、cスタイルのコーディングを振り返り、ポインタを使用することができます。
vector<BigData*> get10BestItems() // returns a vector of pointers
{
vector<BigData*> results ; // vectors of pointers
for ( ........ // iterate over m_map and add 10 best items to results
// ...
return results;
}
しかし、ほとんどの情報源は、絶対に必要でない限り、ポインターを使用しないと言っています。smart_pointersとboostptr_vectorを使用するオプションがありますが、可能であればこれらを避けるようにしています。
マップが静的になることはないので、悪いポインタについてはあまり心配していません。ポインタを処理するためにコードを異ならせる必要がある場合の問題は1つだけです。様式的には、これは快適ではありません。
const BigData& getTheBestItem() // returns a const reference
{
string bestID;
for ( ........ // iterate over m_map, find bestID
// ...
return m_map[bestID] ; // return a referencr to the best item
}
vector<BigData*> get10BestItems() // returns a vector of pointers
{
vector<BigData*> results ; // vectors of pointers
for_each ........ // iterate over m_map and add 10 best items to results
// ...
return results;
};
たとえば、単一のアイテムが必要な場合は、参照を簡単に返すことができます。
最後のオプションは、ハッシュマップを公開し、キーのベクトル(この場合は文字列)を返すことです。
Class A
{
public:
unordered_map<string, BigData> m_map; // lots of data
vector<string> get10BestItemKeys()
{
vector<string> results;
for (........ // iterate over m_map and add 10 best KEYS to results
// ...
return results;
}
};
A aTest;
... // load data to map
vector <string> best10 = aTest.get10BestItemKeys();
for ( .... // iterate over all KEYs in best10
{
aTest.m_map.find(KEY); // do something with item.
// ...
}
最善の解決策は何ですか?スピードは重要ですが、開発のしやすさと安全なプログラミングの実践が必要です。