2017-12-28 17 views
4

std::functionのコストはラムダ関数を扱うためにautoよりも重いと聞きました。効果的な近代的なC + +のitem5。私が望むのは、std::functionがいくつかのサンプルコードでautoより多くのメモリを使用する理由を明らかにすることです。 誰かが私を助けることができますか?はstd :: functionラムダ関数を自動的に格納する関数よりも重い

編集https://github.com/danielhongwoo/mec/blob/master/item5/item5.cpp

から

class Widget { 
public: 
    Widget(int i) : i_(i) {} 
    bool operator<(const Widget& o) { return o.value() > i_; } 
    int value() const { return i_; }; 
private: 
    int i_; 
    int dummy_[1024]; 
}; 

int main() { 
    // performance difference between auto and std::function 
    { 
    auto less1 = [](const auto& p1, const auto& p2) { 
     return *p1 < *p2; 
    }; 
    std::cout << "size of less1: " << sizeof(less1) << endl; 

    function<bool(const std::unique_ptr<Widget>&, 
        const std::unique_ptr<Widget>&)> 
     less2 = [](const std::unique_ptr<Widget>& p1, 
        const std::unique_ptr<Widget>& p2) { 
      return *p1 < *p2; 
     }; 
    std::cout << "size of less2: " << sizeof(less2) << endl; 

    { 
     // auto 
     std::vector<std::unique_ptr<Widget>> ws1; 
     for (auto i = 0; i < 1024*100; ++i) { 
     ws1.emplace_back(new Widget(std::rand())); 
     } 

     auto start = std::chrono::high_resolution_clock::now(); 
     std::sort(ws1.begin(), ws1.end(), less1); 
     auto end = std::chrono::high_resolution_clock::now(); 
     cout << ws1[0].get()->value() << " time: " << (end - start).count() << endl; 
    } 

    { 
     // std::function 
     // 25% slower than using auto 
     std::vector<std::unique_ptr<Widget>> ws2; 
     for (auto i = 0; i < 1024*100; ++i) { 
     ws2.emplace_back(new Widget(std::rand())); 
     } 

     auto start = std::chrono::high_resolution_clock::now(); 
     std::sort(ws2.begin(), ws2.end(), less2); 
     auto end = std::chrono::high_resolution_clock::now(); 
     cout << ws2[0].get()->value() << " time: " << (end - start).count() << endl; 
    } 
    } 
    return 0; 
} 

それはだが、私は、このコードは私がstd::functionが自動を使用するよりも遅くなります使用して示していると思います。しかし、メモリの使用ではありません。私はちょうど実際のコードでそれを証明したい。

+3

[std :: functionのパフォーマンスオーバーヘッドとは何ですか?](https://stackoverflow.com/questions/5057382/what-is-the-performance-overhead-of-stdfunction) –

+0

'std :: function'のオーバーヘッドについて(つまり、' std :: function'は "heavy"です)、通常はパフォーマンスオーバーヘッドが意味されます。そのメモリオーバーヘッドは軽微です(2つの余分なポインタ、私は推測する)。 – Angew

答えて

7

std::functionは、任意の呼び出し可能コードを格納できます。したがって、イレージャーに従事して、任意のタイプのものを保管する必要があります。これは、一般的な場合に動的割り当てを必要とする可能性があり、各呼び出しで間接呼び出し(仮想呼び出しまたは関数ポインタによる呼び出し)が必要であることは間違いなくoperator()です。

ラムダ式のタイプは、それが定義されoperator()(ラムダの閉鎖型)と名前クラスタイプだ、ないstd::functionです。 auto aを使用してラムダを格納すると、この正確なクロージャのタイプはaとなり、オーバーヘッドはありません。

関連する問題