8

再帰ラムダ関数は、通常の再帰関数と比較してオーバーヘッドを引き起こしますか (それらを std::function にキャプチャする必要があるため)?
この関数と、通常の関数のみを使用する同様の関数の違いは何ですか?

int main(int argc, const char *argv[])
{
    std::function<void (int)> helloworld = [&helloworld](int count) {
        std::cout << "Hello world" << std::endl;
        if (count > 1) helloworld(--count);
    }; 
    helloworld(2);
    return 0; 
}
4

3 に答える 3

6

ラムダを として格納することにより、ラムダを再帰的に使用するオーバーヘッドがありますがstd::function、それら自体は基本的にファンクターです。直接比較gccすると、うまく最適化できていないようです。

ラムダの動作を実装する、つまりファンクターを作成すると、gcc再び最適化が可能になります。ラムダの具体的な例は、次のように実装できます

struct HelloWorldFunctor
{
   void operator()(int count) const
   {
      std::cout << "Hello world" << std::endl;
      if ( count > 1 )
      {
         this->operator()(count - 1);
      }
   }
};
int main()
{
   HelloWorldFunctor functor;
   functor(2);
}

私が作成した例では、ファンクタはこの2 番目の demoのようになります。

などの非純粋な関数の呼び出しを導入したとしても、再帰ラムダやカスタム ファンクターを使用しstd::randない場合のパフォーマンスはさらに向上します。これが3 番目のデモです。

結論: a を使用するとstd::functionオーバーヘッドが発生しますが、ユース ケースによっては無視できる場合もあります。この使用法は一部のコンパイラの最適化を妨げるため、これを広範囲に使用するべきではありません。

于 2013-06-12T14:46:40.900 に答える