STL コンテナーを使用すると、コードのデバッグ バージョンの実行が非常に遅くなるため、STL コンテナーを使用するのは本当に嫌いです。デバッグ ビルドで妥当なパフォーマンスを発揮する STL の代わりに、他の人は何を使用していますか?
私はゲーム プログラマーですが、これは私が取り組んできた多くのプロジェクトで問題になっています。すべてに STL コンテナーを使用すると、60 fps を取得するのはかなり困難です。
私はほとんどの作業で MSVC を使用しています。
STL コンテナーを使用すると、コードのデバッグ バージョンの実行が非常に遅くなるため、STL コンテナーを使用するのは本当に嫌いです。デバッグ ビルドで妥当なパフォーマンスを発揮する STL の代わりに、他の人は何を使用していますか?
私はゲーム プログラマーですが、これは私が取り組んできた多くのプロジェクトで問題になっています。すべてに STL コンテナーを使用すると、60 fps を取得するのはかなり困難です。
私はほとんどの作業で MSVC を使用しています。
EASTL は可能ですが、まだ完全ではありません。Electronic Arts の Paul Pedriana は、ゲーム アプリケーションのパフォーマンスに関して、さまざまな STL 実装の調査を行いました 。 /n2271.html
これらの調整の一部は、C++ 標準に含めるために検討されています。
また、EASTL でさえ、最適化されていないケースでは最適化されないことに注意してください。少し前のタイミングでExcelファイルを持っていましたが、紛失したと思いますが、アクセスするには次のようなものでした:
debug release
STL 100 10
EASTL 10 3
array[i] 3 1
私が経験した中で最も成功したのは、独自のコンテナーを展開したことです。これらを array[x] のパフォーマンスに近づけることができます。
私の経験では、オプティマイザーがオフになっているため、適切に設計された STL コードはデバッグ ビルドでの実行が遅くなります。STL コンテナーは、リリース ビルドでインライン化/削除される (軽量の場合) コンストラクターと operator= への多くの呼び出しを発行します。
また、Visual C++ 2005 以降では、リリース ビルドとデバッグ ビルドの両方で STL のチェックが有効になっています。これは、STL を多用するソフトウェアのパフォーマンスを大幅に浪費します。すべてのコンパイル単位に対して _SECURE_SCL=0 を定義することで無効にできます。異なるコンパイル単位で異なる _SECURE_SCL ステータスを持つことは、ほぼ確実に災害につながることに注意してください。
チェックをオフにして 3 番目のビルド構成を作成し、それを使用してパフォーマンスを向上させることができます。ただし、エラーのある配列インデックスなどをキャッチするのに非常に役立つため、チェックをオンにしてデバッグ構成を維持することをお勧めします。
ビジュアル スタジオを実行している場合は、次の点を考慮する必要があります。
#define _SECURE_SCL 0
#define _HAS_ITERATOR_DEBUGGING 0
それはイテレータだけです。どのタイプの STL 操作を実行していますか? メモリ操作の最適化を検討することをお勧めします。つまり、一度に 1 つずつ要素を挿入するために pop/push を使用する代わりに、resize() を使用して一度に複数の要素を挿入します。
大規模でパフォーマンスが重要なアプリケーションの場合、ニーズに合わせて特別に調整された独自のコンテナーを構築することは、時間の投資に値する場合があります。
ここでは実際のゲーム開発について話しています。
Visual C++ を使用している場合は、次を参照してください。
http://channel9.msdn.com/shows/Going+Deep/STL-Iterator-Debugging-and-Secure-SCL/
MS/Dinkware STL が行うすべてのデバッグ モード チェックのさまざまなコストとオプションをカバーする、そのページのリンク。
このようなプラットフォームに依存する質問をする場合は、プラットフォームについても言及することをお勧めします...
あなたの STL は、デバッグ用にチェック済みの実装を使用していると思います。イテレータのオーバーランなどをキャッチするので、これはおそらく良いことです。それがそれほど問題である場合は、それをオフにするコンパイラ スイッチがある可能性があります。ドキュメントを確認してください。
EASTLをチェックしてください。
申し訳ありませんが、コメントを残すことができないので、ここに答えがあります: EASTL は github で利用できるようになりました: https://github.com/paulhodge/EASTL
MSVC はデバッグ ビルドでチェック済み反復子の非常に重い実装を使用しますが、これについては他の人が既に説明しているため、繰り返しません (ただし、そこから始めます)。
あなたにとって興味深いかもしれないもう 1 つのことは、「デバッグ ビルド」と「リリース ビルド」には、おそらく大まかにしか関連しない 4 つの設定の変更が含まれることです。
これらは独立して切り替えることができます。1 つ目は、サイズは増えますが、実行時のパフォーマンスには何の影響もありません。2 番目は多くの関数をより高価にしますが、malloc と free に大きな影響を与えます。デバッグ ランタイム バージョンは、初期化されていないデータのバグを明確にするために、値で接触するメモリを「汚染」するように注意しています。MSVCP* STL 実装では、通常行われるすべての割り当てプーリングも排除されるため、リークは、サブ割り当てされているメモリの大きなチャンクではなく、考えられるブロックを正確に示します。つまり、malloc の呼び出しが多くなる上に、はるかに遅くなります。第3; まあ、それはたくさんのことをします(この質問主題についていくつかの良い議論があります)。残念ながら、シングルステップをスムーズに動作させるには、これが必要です。4 番目は、さまざまな方法で多くのライブラリに影響を与えますが、最も注目すべきは、assert() およびその仲間をコンパイルまたは削除することです。
したがって、これらの選択肢の組み合わせを少なくしてビルドを作成することを検討してください。私はシンボル (/Zi とリンク /DEBUG) とアサート (/DDEBUG) を使用するビルドをよく使用しますが、最適化されています (/O1 または /O2 または使用するフラグ)。バックトレースをクリア (/Oy-) し、通常のランタイム ライブラリ (/MT) を使用します。これは私のリリース ビルドに近いパフォーマンスを発揮し、ある程度デバッグ可能です (バックトレースは問題なく、シングル ステップはソース レベルでは少し奇抜ですが、アセンブリ レベルはもちろん問題なく動作します)。必要な数の構成を持つことができます。リリース 1 のクローンを作成し、デバッグの有用な部分をオンにするだけです。
Ultimate++ には独自のコンテナ セットがあります。ライブラリの残りの部分とは別に使用できるかどうかはわかりません: http://www.ultimatepp.org/
ACE ライブラリはどうですか? これは同時通信ソフトウェア用のオープンソースのオブジェクト指向フレームワークですが、いくつかのコンテナー クラスもあります。
Bruno Preiss による C++ のオブジェクト指向設計パターンを使用したチェックアウト データ構造とアルゴリズム http://www.brpreiss.com/
STL コンテナは、デバッグ中やその他の場所で「非常にゆっくり」実行するべきではありません。おそらく、あなたはそれらを悪用しています。デバッグで ElectricFence や Valgrind などに対して実行していませんか? 多くの割り当てを行うものはすべて遅くなります。
すべてのコンテナーはカスタム アロケーターを使用できます。これは、パフォーマンスを向上させるために使用する人もいますが、自分で使用する必要はありませんでした。