前回のカスタムデリータ使うときの話で

http://d.hatena.ne.jp/gintenlabo/20110121/1295626957にstd::functionの型消しの影響で最適化かかりにくいし、実行効率・メモリ効率も悪いよね的な事が書かれていたので、これは実測して試してみるしかないネという事なのでした。

#include <iostream>
#include <memory>
#include <functional>
#include <boost/timer.hpp>
using namespace std;

template<class T, class D>
std::unique_ptr<T, D> make_unique_ptr( T* p, D d ) {
  return std::unique_ptr<T, D>( p, std::forward<D>(d) );
}

class Hoge{
public:
  static int c_count;
  static int d_count;
  Hoge():n(0){++c_count;}
  ~Hoge(){}
private:
  int n;
};

int Hoge::c_count = 0;
int Hoge::d_count = 0;

int main(){
  boost::timer t;

  t.restart();
  for(size_t i=0; i < 1000000U; ++i){  
    auto hoge = make_unique_ptr(new Hoge(),[](Hoge* hoge){Hoge::d_count++; delete hoge;});
  }
  cout << Hoge::c_count << endl;
  cout << Hoge::d_count << endl;
  cout << t.elapsed() << "秒かかりました" << endl;

  t.restart();
  for(size_t i=0; i < 1000000U; ++i){
    std::unique_ptr<Hoge,std::function<void(Hoge*)>> test(new Hoge(),[](Hoge* fuga){Hoge::d_count++; delete fuga;});
  }
  cout << Hoge::c_count << endl;
  cout << Hoge::d_count << endl;
  cout << t.elapsed() << "秒かかりました" << endl;
}

出力結果

1000000
1000000
0.187秒かかりました
2000000
2000000
0.245秒かかりました

うちの環境ではだいたい1.2〜1.8倍くらい時間かかるっぽい。
……って、えらく違うなコレ。マジか。

  • - - - - -

コメントで指摘貰ったので若干修正

  • - - - - -

2011/10/04
std::functionが例外を投げた場合にリークするとの指摘
これは……std::shared_ptr最強説か……(ただし無駄コスト発生)
変にトリッキーな事をするものじゃないということですかのう