11

これは私がここに投稿する最初の質問なので、何も悪いことをしないことを願っています。

std::for_each私の質問は、最新スタイルのC ++ 11ループ( 、範囲ベースのfor)と古いスタイルのC ++ループ( )のパフォーマンスに関するものfor (...; ...; ...)です。私が理解したことから、現代​​のC ++のモットーは、「パフォーマンスに妥協のない表現度」であるように思われます。最新のC++スタイルは、パフォーマンスの低下がほとんどないかまったくない、安全でクリーンな高速コードを実現し、場合によっては、古いスタイルのC++よりもパフォーマンスが向上します。

ここで、このゲインがループに関してどれほど大きいかを評価するために、少しテストを行いました。最初に、次の3つの関数を作成しました。

using namespace std;

void foo(vector<double>& v)
{
    for (size_t i = 0; i < v.size(); i++)
    {
        v[i] /= 42;
    }
}

void bar(vector<double>& v)
{
    for (auto& x : v)
    {
        x /= 42;
    }
}

void wee(vector<double>& v)
{
    for_each(begin(v), end(v), [] (double& x)
    {
        x /= 42;
    });
}

main()次に、このように呼び出してパフォーマンスを比較しました(のループ内の3行を適切にコメント/コメント解除します。

vector<double> make_vector()
{
    vector<double> v;
    for (int i = 0; i < 30000; i++) { v.push_back(i); }
    return v;
}

int main()
{
    time_t start = clock();

    auto v = make_vector();
    for (int i = 0; i <= 50000; i++) 
    { 
        // UNCOMMENT THE FUNCTION CALL TO BE TESTED, COMMENT THE OTHERS

        foo(v);
        // bar(v); 
        // wee(v);
    }

    time_t end = clock();
    cout << (end - start) << endl;

    return 0;
}

のループ内の行をコメント化/コメント解除main()し、古いスタイルのループをベースラインとして使用して得られたプログラムの各バージョンの10回以上の実行を平均すると、範囲ベースのforループのパフォーマンスは約1.9倍低下し、std::for_eachラムダのパフォーマンスは約2.3倍悪くなります。

これをコンパイルするためにClang3.2を使用しましたが、MS VC11を試していません(WinXPで作業しています)。

同等の実行時間を得るという私の期待を考慮して、私の質問は次のとおりです。

  1. 私は明らかに間違ったことをしましたか?
  2. そうでない場合、2倍のパフォーマンスペナルティがモダンスタイルのループを採用しない正当な理由ではないでしょうか?

最新のC++スタイルで記述されたコードの明快さと安全性は、パフォーマンスの低下の可能性を補うと信じていますが、明快さと安全性の間にトレードオフがないという声明にはまったく同意しません。側と反対側のパフォーマンス。

私は何かが足りないのですか?

4

2 に答える 2

12

違いは、コンパイラで最適化を有効にしない場合にのみ現れるようです。

Clang では、-O[0-3]フラグを使用して最適化を有効にすることができます。

于 2012-12-27T15:04:35.687 に答える