c ++でchar配列の代わりにstd :: stringのみを使用し、配列の代わりにstd :: vector / listのみを使用することに実用的な制限はありますか?

StackOverflow https://stackoverflow.com/questions/801385

質問

コードでは、ベクトル、リスト、文字列、wstringsを強引に使用しています。代わりにcharsとwcharsを時々使用する配列に興味を持たせる必要のあるキャッチ22がありますか?

基本的に、標準のテンプレートライブラリをサポートする環境で作業している場合、プリミティブ型を使用する方が実際には良いですか?

役に立ちましたか?

解決

99%の時間と99%の標準ライブラリの実装では、std :: vectorsが十分に高速であり、それらを使用することで得られる利便性と安全性は、小さなパフォーマンスコストを上回ることがわかります。

ベアメタルコードが本当に必要な非常にまれなケースでは、ベクトルをCスタイルの配列のように扱うことができます。

vector <int> v( 100 );
int * p = &v[0];
p[3] = 42;

C ++標準では、ベクトルが連続して割り当てられることが保証されているため、これが機能することが保証されています。

文字列に関しては、利便性の要因が圧倒的に多くなり、パフォーマンスの問題は解消される傾向があります。 Cスタイルの文字列に気を取られた場合、strlen()のような関数の使用にも戻ります。これは本質的に非常に効率的ではありません。

リストについては、独自の実装であれ標準であれ、リストを使用する前に、2回、おそらく3回考える必要があります。コンピューティングの問題の大部分は、ベクトル/配列を使用することでより適切に解決されます。理由リストは、教科書やトレーニングコースの作成者がポインタと動的割り当てを一度に説明するために使用する便利なデータ構造であるため、文献に頻繁に登場します。ここでは、元トレーニングコースのライターとして話しています。

他のヒント

STLクラス(ベクター、文字列など)に固執します。これらは、より安全で使いやすく、生産性が高く、メモリリークの可能性が低く、少なくとも、デバッグ時(Visual C ++)に、追加の実行時の境界チェックを行います。

次に、パフォーマンスを測定します。ボトルネックがSTLクラスにあると特定した場合は、Cスタイルの文字列と配列の使用に移行してください。

私の経験から、ベクターまたは文字列の使用にボトルネックが生じる可能性は非常に低いです。

1つの問題は、要素にアクセスする際のオーバーヘッドです。インデックスを使用して要素にアクセスする場合、ベクトルと文字列を使用しても、最初にバッファーアドレスを取得してからオフセットを追加する必要があります(手動で行うのではなく、コンパイラーがそのようなコードを出力します)。生の配列では、すでにバッファアドレスを持っています。この余分な間接化は、特定の場合にかなりのオーバーヘッドにつながる可能性があり、パフォーマンスを改善したい場合はプロファイリングの対象となります。

リアルタイムの応答が必要ない場合は、アプローチに固執します。文字より安全です。

自分で何かをすることでパフォーマンスやメモリ使用量が向上するシナリオに時々出くわすことがあります(たとえば、std :: stringには通常約24バイトのオーバーヘッドがあり、std :: string自体のポインターには12バイトあります) 、および動的に割り当てられた部分のヘッダーブロック)。

私はstd :: stringからconst char *への変換が顕著なメモリ(数十MB)を節約するプロジェクトに取り組んできました。これらのプロジェクトは典型的なものだとは思いません。

ああ、STLを使用するとコンパイル時間が遅くなり、ある時点で問題になる可能性があります。プロジェクトの結果、1 GBを超えるオブジェクトファイルがリンカーに渡される場合、テンプレートの膨張の程度を考慮することをお勧めします。

文字列のメモリオーバーヘッドが問題となるいくつかのプロジェクトに取り組んできました。

アプリケーションのスケーリング方法を事前に検討する価値があります。制限のない数の文字列を保存する必要がある場合、 const char * をグローバルに管理された文字列テーブルに使用すると、大量のメモリを節約できます。

しかし、一般的には、特に理由がない限り、STLタイプを使用してください。

デフォルトのメモリ割り当て手法はベクトル用のバッファであり、文字列は現在割り当てられているメモリが使い果たされるたびにメモリ量の2倍を割り当てるものだと思います。これは無駄です。もちろん、カスタムアロケーターを提供できます...

他に考慮すべきことは、スタックとヒープです。静的なサイズの配列と文字列がスタックに置かれるか、少なくともコンパイラーがメモリ管理を処理します。新しいコンパイラーは、関連するC99 / C ++ 0x機能を提供する場合、動的にサイズ調整された配列も処理します。ベクトルと文字列は常にヒープを使用するため、非常に厳しい制約がある場合はパフォーマンスの問題が発生する可能性があります。

おおまかに言って、プロジェクトの速度/メモリオーバーヘッドで問題が発生しない限り、既存のものを使用してください。アプリケーションのパフォーマンスへの影響。 (つまり、「時期尚早な最適化を避ける」)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top