3

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

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

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

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

4

5 に答える 5

26

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

void f(const std::vector<int>& v)

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

于 2010-09-02T15:53:01.377 に答える
15

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

ベクトルで値渡しではなく、参照渡しを const に使用した方がよいことに注意してください。

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

于 2010-09-02T15:51:48.690 に答える
4

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

不明な場合は、プロファイリングしてください。現れることはないと思います。

于 2010-09-02T15:51:04.360 に答える
3

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

于 2010-09-02T15:57:30.773 に答える
0

ベクトルの内容へのシーケンシャル アクセスのみが必要な場合 (悲しいことに、あなたの例は一見ランダム アクセスを示しているため、これは機能しませんが、これは単なる例に過ぎない可能性があります)、イテレータを使用してベクター。この最適化は、完全なコンパイラ最適化がオンになっているプレーン配列でも顕著な違いを生むのを見てきました。

于 2010-09-02T17:42:09.300 に答える