2017-05-17 7 views
2

struct {int、int、int、int}型のエントリが10,000,000件ありました。私はQHashまたはQMapを使用してそれらを格納するとき、それは確かに、それはおよそQHash大量のデータを保存する

10,000,000 * 4 * 4 (sizeof integer) <= 153 MB 

を取る必要があり、大量のメモリを占有しているが、私は私のデータをロードしたときにこれが発生し、どのように、なぜそれが、QHashとQMapの両方のために約1.2 GBになります速度とメモリの両方で最適化できますか?(他のデータ構造やqmapやqhashへのいくつかのトリックを通して)

+2

'QHash'と' QMap'は連想型のコンテナーです:あなたの4-int構造体を推測することは保存された値です、どのようなキーのタイプですか? – wasthishelpful

+0

@ qhash()のQtPrivate :: QHashCombineを使用してQtPrivate :: QHashCombineを格納している他の4つの整数は – abdolahS

+1

ですが、順次配列の場合は153 MBに近くなりますが、マップには追加のデータ構造オーバーヘッドとヒープ割り当てオーバーヘッドがあります。まだそれほど多くはありません。 – dtech

答えて

2

コメントには、別の4つのintをキーとして使用していると言われています。実際には8個のintを格納するのではなく、4個を格納しています。それ以外は、QHashはキーに基づいて値を効率的に検索するためにハッシュの値を格納する必要があります。ハッシュは符号なし整数なので、4バイトごとに9個の値が得られます。最大350 MBの合計です。

また、内部QHash又はQMapdata structure alignment requirementsを満たすために、例えば、その要素の間にいくつかのパディングを使用してもよいです。パディングは1バイトの乗数です。つまり、10万の要素の場合、を少なくともの数十メガバイト追加することがあります。

はまた、QHashQMapは単なる生のデータではありません - 彼らは両方など、その内部データ構造への追加のポインタを使用し、まだ単一のエントリは、あなたが予想より多くのスペースを取ると別の理由です。

膨大なデータサイズの別の原因は、効率の理由から、これらのクラスにいくつかの追加の値を保存して、メソッドのいくつかを呼び出すときにあらかじめ計算される可能性があるということです。

最後に、QHashは、効率の理由から(不要なコピーを避けるために)、現在の要素よりも多くのメモリを予約します。私は、コピーがより高価になるので、サイズが大きければ大きいほど、ちょうどその場合に備えてより多くのメモリが必要になると思います。 capacity()メソッドを呼び出すことで、予約済みのメモリを事前に確認することができます。予約されているメモリの量を制限する場合は、squeeze()メソッドを呼び出して、現在格納されている要素を格納するのに十分なだけメモリを調整します。

+0

_squeeze_を使用する代わりに、_reserve_を使用する方が良いです。なぜなら、彼は要素の数を知っているからです。 – Zlatomir

+0

reserve()を呼び出して要素を挿入すると、インプリメンテーションは挿入プロセス中に空き領域を確保できるため、最後にsqueeze()を呼び出してしまうことがあります。 – KjMag

関連する問題