c++11 lambdaの効率


c++11の新しい特性lambda関数の効率テスト
c++stlのアルゴリズムを使用する場合、多くの場合、関数オブジェクトまたは関数ポインタを入力する必要があります.effective stlの本の説明によると、伝達関数オブジェクトの実行効率は関数ポインタよりも高いです.なぜなら、アルゴリズム関数では、関数オブジェクトに基づいて呼び出しの関数をインライン展開することができ、関数ポインタが入力されると、このようなインライン展開の技術は実現できないため、多くの関数呼び出しが存在するためである.
c++11の新しい特性にはlambda関数が提供され、lambda関数は匿名関数であり、具体的にはc++11ウィキペディアを参照して説明することができる.本稿では,lambda関数を用いる場合,コンパイラはどのように処理されるのか,1,関数オブジェクトのようにインライン展開できるのか,2,関数ポインタのように必ず関数呼び出し実現を行うのかを主に論じる.
私たちはcode::blocks IDEを使用しています.プログラムの実行タイミング機能を提供しています.プログラムが終了した後、実行時間を印刷します.この3つの場合のプログラムの比較に時間がかかります.3つの試験コードはいずれも−O 2最適化を用いた.Lambdaのテストコードは次のとおりです.
int main()
{
    vector vInt;
    const int SIZE_VECTOR = 10000000;
    for (int i = 0; i < SIZE_VECTOR; ++i)
    {
        vInt.push_back(i);
    }
    for (int i = 0; i < 100; ++i)
    {
        for_each(vInt.begin(), vInt.end(), [](int ele){ 
		static long long sum = 0; 
		sum += ele; 
	});
    }

    return 0;
}

このコードは純粋なテストで使用され,強い機能を持たず,静的変数sumを使用するのは関数ポインタと関数オブジェクトの内容が一致することを保証するためである.このコードの実行時間は約1.550 sです.実行時間は毎回異なりますが、この値の近くにあります.
次に、関数オブジェクトを使用した実行時間をテストします.コードは次のとおりです.
struct SumUpOperator
{
    inline void operator ()(int ele){
        static long long sum = 0;
        sum += ele;
    }
};

int main()
{
    vector vInt;
    const int SIZE_VECTOR = 10000000;
    for (int i = 0; i < SIZE_VECTOR; ++i)
    {
        vInt.push_back(i);
    }
    for (int i = 0; i < 100; ++i)
    {
        for_each(vInt.begin(), vInt.end(), SumUpOperator());
    }

    return 0;
}

関数オブジェクト内で、オペレータ()関数の内容はlambdaの内容と完全に一致します.実行時間は1.600 sです.基本的にlambda関数を使用する場合と同じです.
次に、関数ポインタプログラムを使用した実行時間をテストします.コードは次のとおりです.
inline void sumUp(int ele)
{
    static long long sum = 0;
    sum += ele;
}

int main()
{
    vector vInt;
    const int SIZE_VECTOR = 10000000;
    for (int i = 0; i < SIZE_VECTOR; ++i)
    {
        vInt.push_back(i);
    }
    for (int i = 0; i < 100; ++i)
    {
        for_each(vInt.begin(), vInt.end(), sumUp);
    }

    return 0;
}

関数の内容は、以前のものと完全に一致しています.実行時間:4.550 s.これは以前の2つの状況よりずっと遅い.
このようにlambda関数の使用効率は、関数オブジェクトの使用と同じであり、関数ポインタよりも速いことを示します.コンパイル期間中にコードをインライン展開し、関数呼び出しの時間を短縮できます.
効率の問題を心配することなくlambda関数を安心して使用できるようになりました.
最後に、コンパイラは実際にlambda関数を関数オブジェクトに変換するので、関数オブジェクトを使用するのと同じように効率的です.