2012-03-14 8 views
2

どのSTLコンテナがパフォーマンスの点で '継続的に'変化する要素のコレクションに最も適しているかを知りたいと思います。これらの要素は、指定された表示空間内のオブジェクトを表し、ビューの変更やオブジェクトの移動や表示の移動に伴い、オブジェクトのコレクションを更新する必要があります。ビューが更新されるたびに、私はUIDでソートされたシーンの中にあるオブジェクトのstd :: vectorを取得します(このリストAを呼び出すことができます)。 Iがthat checkをrunするwant:継続的に追加および削除される一連の要素に使用するコンテナ

  • がactually sceneでno longer thingsのcurrent listからvisibleあるobjectsをremoves List Aにbased(このListのBをcall)

  • はnew objectsをadds今Bをリストに表示されていること、再びリストAに基づいて4000個のオブジェクトへ

二つは、おそらく今まで見たオブジェクトの数の上限です。オブジェクトのUIDは数十億に達するので、私はビットマップされたベクトルを使用することはできません。私はリストBを更新するためのリストB.私の提案戦略のためのstd ::マップを使用することができます考えていたことである。「i」はリストBの各UIDに対して

  • 、UIDの検索がIは(リストAにstd :: lower_boundを使用して)。 UIDがリストAに存在しない場合は、リストBから削除します。

  • リストAの各UIDについて、リストBのUID 'i'を検索します(std :: map :: lower_boundを使用) 。リストBにUIDが存在しない場合は、追加します。

私は、具体的には、適切なコンテナタイプを使用している場合、いくつかのアドバイスをしたいと思います。私はstd :: vectorがリストBのために良い選択になるとは思っていませんでした。なぜなら、挿入/削除は高価なので、私はstd :: findよりもバイナリ検索を使いたければ明示的にソートする必要があったからです。しかし、それ以外のコンテナの種類や、それがより適切かどうかはわかりません。

リストBを更新するために選択した一般的な方法が最も効率的な方法であるかどうかを知りたいと思っています。

+3

はこれがまさにこのセットではありませんか? –

+1

Deos this help? http://stackoverflow.com/questions/471432/in-which-scenario-do-i-use-a-particular-stl-container –

+1

AにないBからすべてを削除し、Bにすべてを追加するとAではあるがBではなく、あなたの結果はAのコピーを作ることとどう違うのですか? –

答えて

1

あなたの問題のようなサウンドは、セット操作を必要とします。 ListAにないオブジェクトをシーンから削除することは、設定された差分操作です。シーンに含まれていないListAからのオブジェクトの追加は、集合体の操作となります。ビットマップに対してデータが適切に整理されていない場合、通常、セット操作はハッシングの候補です。

オペランドの1つをハッシュのようなデータ構造ではないセット操作にすることができます。それはあなたが反復するものであり、行動を(償却された)O(N)を保つために、他のもので検索します。

# left operand is list, right is hash: 

set_diff (list x, hash y): 
    val ret = make_hash() 
    for i in x: 
     if not y[i] 
      ret[i] = i 
    return ret 

# vice versa 

set_diff (hash x, list y) 
    val ret = copy_hash(x) 
    for i in y: 
     if ret[i] 
      delete ret[i] 
    return ret    

ところで、なぜlower_boundを使用して検索しますか。 IDはユニークではないのですか?

+0

lower_boundはバイナリ検索と私のデータ(少なくともListA)が順序付けされているためです。 ..(これはstd :: find rightよりも優れていますか?)私は実際にここでハッシュコンテナを使用する方法に従っていません - ハッシュ関数を定義するにはどうすればよいですか(IDは一意ですが、ランダムであると仮定して1から数十億まで変化します) – Prismatic

+0

右しかし、あなたはまた、リストBのUID 'i'を検索しました(std :: map :: lower_boundを使用して)* – Kaz

+0

他に何を使用するべきですか? []演算子の使用について話していますか?または私はmap :: findを使うべきですか?それらはすべて対数です。 http://www.cplusplus.com/reference/stl/map/ – Prismatic

0

あなたが決定する必要があるのはSTL Containersで、操作の複雑さまでスクロールします。 あなたの選択はstd::liststd::dequeおよびstd::vectorの間であり、後者はすべての中で最も遅く、前者は最も速いです。今、それらのうちのどれがあなたのすべての要件を提供していますか?理想的にはstd::listを使用します。挿入はO(n)です。std::dequeはO(n + x)です。ここでxは挿入ポイントまでの要素の数です。しかし、私はあなたが要素を取得するためにstd::deque::at()が必要になると思う。私は両方のリストでこれが必要だと思うので、std::dequeを使うべきです。

+0

セットやプロファイリングについては言及していません。ベクトルが最も速くなる可能性は非常に高いです。 –

+0

'std :: vector'はそれらの中で最も遅く、' std :: set'は連想型コンテナですが、私はあなたの意見を見ませんか? –

+0

@ g241なので、 'std :: set'が連想型のコンテナであればどうでしょうか?これはまだ、この種のtask_のために設計されたコンテナです。それはOPが説明する操作のための特別なメンバーを持っています。 'std :: vector'はランダム挿入/削除の最悪_asymptotic time_を持っていますが、' std :: list'は最も良い_asymptotic time_を持っていますが、 'vector'はキャッシングのためにいつも' list'より優れています。 [Bjarne StroustrupのGoingNative2012のスライド](http://ecn.channel9.msdn.com/events/GoingNative12/GN12Cpp11Style.pdf)(スライド45) –

0

両方についてboost unordered setを試しましたか?

ここにはセットが必要ですが、ソートする必要はないようです。その場合、最良の候補は順序付けられていないセットです。あなたが望むもの(単なる物の集合)を与えることに加えて、それはソートに伴う(小さな)パフォーマンスヒットを取り除きます。

+0

std :: unordered_setは現在標準の一部であり、追加の必要はありません。 –

+0

"順序付けられていないセット"は、 "セット"を意味する冗長なフレーズです。 C++は以前は無駄に順序を保持したシーケンスを使用してセットを表していましたが、現在は実際のセットがあります。興味深い! – Kaz

+0

これはC++ 11の新機能ですか? http://www.cplusplus.com/reference/stl/set/によると、それは厳密な弱い順序に従う。 – Carl

関連する問題