web-dev-qa-db-ja.com

std :: arrayと配列のパフォーマンス

次のような非常に単純な配列を作成する場合

int myArray[3] = {1,2,3};

代わりにstd::arrayを使用する必要がありますか?

std::array<int, 3> a = {{1, 2, 3}};

通常のものよりもstd :: arrayを使用する利点は何ですか?より高性能ですか?コピー/アクセスの取り扱いが簡単ですか?

46
Arcyno

std::arrayを通常のものよりも使用する利点は何ですか?

わかりやすい値のセマンティクスを備えているため、値によって関数とやり取りすることができます。そのインターフェイスにより、サイズを見つけやすくなり、STLスタイルの反復子ベースのアルゴリズムで使用しやすくなります。

より高性能ですか?

まったく同じでなければなりません。定義では、それは唯一のメンバーとして配列を含む単純な集合体です。

コピー/アクセスの取り扱いが簡単ですか?

はい。

65
Mike Seymour

std::arrayは、Cスタイルの配列を囲む非常に薄いラッパーで、基本的に次のように定義されます。

template<typename T, size_t N>
class array
{
public:
    T _data[N];
    T& operator[](size_t);
    const T& operator[](size_t) const;
    // other member functions and typedefs
};

これは 集合 であり、基本型のように使用できます(つまり、値渡し、割り当てなどができますが、標準のC配列は別の配列に直接割り当てたりコピーしたりすることはできません。アレイ)。いくつかの標準的な実装(お気に入りのIDEまたは直接開く<array>)、これは非常に読みやすく理解しやすいC++標準ライブラリの一部です。

24
vsoftco

std::arrayは、他のC++コンテナのセマンティクスのような「通常の」値を与えるC配列のゼロオーバーヘッドラッパーとして設計されています。

追加の機能を引き続き利用しながら、実行時のパフォーマンスの違いに気付かないでください。

std::arrayスタイルの配列の代わりにint[]を使用することは、C++ 11またはboostを手元に持っている場合には良いアイデアです。

17
Baum mit Augen

std::arrayには値のセマンティクスがありますが、生の配列にはありません。つまり、std::arrayをコピーして、プリミティブ値のように扱うことができます。関数引数として値または参照によってそれらを受け取り、値によってそれらを返すことができます。

std::arrayを決してコピーしない場合、生の配列とパフォーマンスの違いはありません。コピーを作成する必要がある場合、std::arrayは正しいことを行いますが、それでも同等のパフォーマンスが得られます。

4
b4hand

より高性能ですか?

まったく同じでなければなりません。定義では、それは唯一のメンバーとして配列を含む単純な集合体です。

特定のプラットフォームによっては、std :: arrayがC-arrayと比較して常に同じアセンブリコードを生成するとは限らないため、状況はより複雑に思われます。

Godbolt.orgでこの特定の状況をテストしました。

#include <array>
void test(double* const C, const double* const A,
           const double* const B, const size_t size) {
  for (size_t i = 0; i < size; i++) {
    //double arr[2] = {0.e0};//
    std::array<double, 2> arr = {0.e0};//different to double arr[2] for some compiler
    for (size_t j = 0; j < size; j++) {
      arr[0] += A[i] * B[j];
      arr[1] += A[j] * B[i];
    }
    C[i] += arr[0];
    C[i] += arr[1];
  }
}

GCCとClangは、C-arrayバージョンとstd :: arrayバージョンの両方で同一のアセンブリコードを生成します。

ただし、MSVCとICPCは、アレイのバージョンごとに異なるアセンブリコードを生成します。 (ICPC19を-Ofastおよび-Os、MSVC -Oxおよび-Osでテストしました)

なぜそうなのか、私にはわからない(std :: arrayとc-arrayのまったく同じ振る舞いを期待するだろう)。おそらく、さまざまな最適化戦略が採用されています。

少し余分に:icpcにバグがあるようです

#pragma simd 

いくつかの状況でc-arrayを使用する場合のベクトル化(c-arrayコードは誤った出力を生成します。std:: arrayバージョンは正常に動作します)。残念ながら、非常に複雑なコードの最適化中にその問題を発見したため、まだ実用的な最小限の例はありません。 c_array/std :: arrayと#pragma simdについて何かを誤解しただけではないと確信したら、インテルにバグ報告を提出します。

3
Henryk