1

ネストされたベクトル内に格納される巨大な行列を作成しています:

typedef vector<vector<pair<unsigned int, char>>> Matrix;

外側のベクトルには、最終的に最大 220 ペアを含む最大 400.000 個のベクトルが含まれます (ほとんどのベクトルはそれ以下です)。これには約 1GB の RAM が必要で、次のように実行されます。

Matrix matrix;
for (unsigned int i = 0; i < rows; i++) {
    vector<pair<unsigned int, char>> row;
    for (unsigned int j = 0; j < cols; j++) {
        // ...calculations...
        row.push_back( pair<unsigned int, char>(x, y) );
    }
    matrix.push_back(row);
}

最初の 20% は非常に高速ですが、外側のベクトルが大きくなるほど、プロセス全体が遅くなります。ある程度の最適化は可能だと確信していますが、私はこの分野の専門家ではありません。これをスピードアップするための簡単なトリックはありますか? または、私の試みに重大な誤りがありますか?

4

4 に答える 4

8

単一の 1 次元ベクトルを使用して、一部の関数/クラスで行、列のインデックスをラップする方がよいでしょう。このようにして、行列全体のメモリが連続していることが保証されます。

push_backそして、前もって行列全体を割り当てる代わりに、次のようにします。

std::vector<pair<unsigned int, char>> matrix(rows * cols);
于 2012-08-17T11:46:46.233 に答える
2

VS 2010コンパイラを使用すると、次のことが最も効果的に機能することがわかりました。

Matrix matrix;
matrix.reserve(rows);

vector<pair<unsigned int, char>> row;
row.reserve(cols);

for (unsigned int i = 0; i < rows; i++) {
    for (unsigned int j = 0; j < cols; j++) {
        // ...calculations...
        row.push_back( pair<unsigned int, char>(x, y) );
    }
    matrix.push_back(row);
    row.clear();
}

すべての行を構築するために使用される単一のベクトルを作成することは、毎回「cols」エントリにメモリを割り当てる新しいベクトルを作成するよりもはるかに少ないメモリを消費します。なぜそうなのかよくわかりません。

ただし、Andreasの回答は私の特定のケースの解決策にすぎず、Andreasの回答はそのような最適化に必要な一般的な情報を提供していたため、私はAndreasの回答を受け入れています。

于 2012-08-18T10:11:32.403 に答える
2

明らかな最適化から始めます。値の入力を開始する前に行数 (または使用可能な上限) がわかっている場合は、事前にスペースを確保してください。多くの値を push_back するときに費やされる最も多くの時間は、メモリの再割り当てと既に含まれている値のコピーに費やされます。

Matrix matrix(rows);
for(unsigned i = 0; i < rows; i++) {
    vector<pair<unsigned int, char>> row(cols);
    for(unsigned j; j < cols; j++) {
        row[j] = // value
    }
    matrix[i] = row;
}
于 2012-08-17T12:36:42.943 に答える
1

問題は、外部ベクトルが大きくなると大量のデータがコピーされることです。typedef を次のように変更することを検討してください

typedef vector< shared_ptr< vector<pair<unsigned int, char>> > > Matrix;

値の入力を開始するmatrix.reserve(rows)前に実行します。

于 2012-08-17T12:20:59.087 に答える