[解決済み】C++で配列とstd::vectorの使い分け、性能の差は何?
2022-04-03 16:53:59
質問
C++のコースでは、新しいプロジェクトではもうC++の配列は使わないようにと言われています。私の知る限り、Stroustroup自身も配列を使用しないよう勧めています。しかし、パフォーマンスに大きな違いがあるのでしょうか?
どのように解決するのか?
C++の配列を使用し
new
(つまり、動的配列の使用)は避けるべきです。サイズを把握しなければならないという問題がありますし、手動で削除したり、いろいろと家計簿をつけなければなりません。
スタック上の配列を使うのもお勧めしません。範囲チェックができないし、配列を渡すとそのサイズに関する情報が失われるからです(配列からポインタへの変換)。そのため
boost::array
その場合、C++の配列を小さなクラスでラップし、そのクラスで提供される
size
関数とそれを反復処理するイテレータがあります。
では std::vectorとC++のネイティブ配列の比較 (インターネットから引用)。
// Comparison of assembly code generated for basic indexing, dereferencing,
// and increment operations on vectors and arrays/pointers.
// Assembly code was generated by gcc 4.1.0 invoked with g++ -O3 -S on a
// x86_64-suse-linux machine.
#include <vector>
struct S
{
int padding;
std::vector<int> v;
int * p;
std::vector<int>::iterator i;
};
int pointer_index (S & s) { return s.p[3]; }
// movq 32(%rdi), %rax
// movl 12(%rax), %eax
// ret
int vector_index (S & s) { return s.v[3]; }
// movq 8(%rdi), %rax
// movl 12(%rax), %eax
// ret
// Conclusion: Indexing a vector is the same damn thing as indexing a pointer.
int pointer_deref (S & s) { return *s.p; }
// movq 32(%rdi), %rax
// movl (%rax), %eax
// ret
int iterator_deref (S & s) { return *s.i; }
// movq 40(%rdi), %rax
// movl (%rax), %eax
// ret
// Conclusion: Dereferencing a vector iterator is the same damn thing
// as dereferencing a pointer.
void pointer_increment (S & s) { ++s.p; }
// addq $4, 32(%rdi)
// ret
void iterator_increment (S & s) { ++s.i; }
// addq $4, 40(%rdi)
// ret
// Conclusion: Incrementing a vector iterator is the same damn thing as
// incrementing a pointer.
注意: 配列を
new
を割り当て、クラス以外のオブジェクト(例えば、プレーンな
int
) またはユーザー定義のコンストラクタを持たないクラス
と
を使用すると、要素が初期化されずに済みます。
new
-割り当てられた配列は、パフォーマンス上の利点があります。
std::vector
は、構築時にすべての要素をデフォルト値 (たとえば int は 0) に初期化します (気づかせてくれた @bernie に感謝します)。
関連
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] Java の配列を表示する最も簡単な方法は何ですか?
-
[解決済み] 配列の場合、なぜ a[5] == 5[a] になるのでしょうか?
-
[解決済み] JavaScriptで配列を比較する方法は?
-
[解決済み] 簡単な面接問題が難しくなった:1~100の数字が与えられたとき、ちょうどk個の数字が欠けていることを見つけなさい。
-
[解決済み] C++11の'typedef'と'using'の違いは何ですか?
-
[解決済み] JavaScriptで2つの配列の差を取得する方法は?
-
[解決済み] Rubyのmapとcollectの違い?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】構造体のベクター初期化について
-
[解決済み】C-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み】C++ 式はポインタからオブジェクトへの型を持っている必要があります。
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】std::vectorは普通の配列よりそんなに遅いの?