3


0

std :: vectorの最適化
std

vectorから多くの値を読み取るループが私のプログラムのボトルネックであると仮定すると、変更することが提案されました

void f(std::vector v)
{
    ...
    while (...)
    {
        ...
        int x = v[i] + v[j]
        ...
    }
}

to

void f(std::vector v)
{
    int* p_v = &v[0];
    ...
    while (...)
    {
        ...
        int x = p_v[i] + p_v[j]
        ...
    }
}

[]演算子をバイパスすることにより、実際にパフォーマンスが向上しますか?

5 Answer


26


この関数を呼び出すたびにベクトル全体をコピーすることがボトルネックになる可能性が高くなります(一見)。 代わりに次のようにしないのはなぜですか?

void f(const std::vector& v)

いずれにせよ、ボトルネックがどこにあるかを決して仮定しないでください-最初に測定し、確実にわかったら遅いコードを調整してください。


15


いいえ、パフォーマンスに影響はありません。

ベクトルの値渡しではなく、参照渡しによる定数の使用をお勧めします。

編集:その構文については、@ Steve Townsendの答えを参照してください。


4


いいえ、実質的ではありません。 (おそらく)わずかなパフォーマンスの向上を犠牲にして、コードを読みにくくしています。 とにかく、最適化されたビルドでコンパイラが `operator []`の呼び出しをインライン化しない場合、私は驚くでしょう。

よくわからない場合は、プロファイルを作成してください。 私はそれが決して現れないことを想像します。


3


パフォーマンスに関するほとんどの質問に対する標準的な答えは、プロファイラーを使用して、これがボトルネックであるかどうかを確認し、変更が役立つかどうかを確認することです。 ただし、この場合、特に良いアドバイスだとは思いません。 このようなコードに対して十分なコンパイラーからの出力を見てきましたが、その2つが同一の命令ストリームを生成するという事実を説明するために_ほぼ_行きます。 理論的には、_could_が間違っている(かなりの数のコンパイラーで遊んだことはありますが、実際に遊んだことのない他のコンパイラーもあります)が、実際はそうだとしたら驚くでしょう。 異なる命令または2つの先行する(ループの外側)が存在する可能性がありますが、ループ内にあるものは同一であると予想されます。


0


ベクトルのコンテンツへのシーケンシャルアクセスのみが必要な場合(そして悲しいことに、サンプルはランダムアクセスのように見えるため、これは機能しませんが、単なる例にすぎません)、イテレータを使用して速度を大幅に向上させることができますベクター。 この最適化は、完全なコンパイラー最適化がオンになっている単純な配列でも顕著に変化するのを見てきました。