5

私は現在、ネットワークソフトウェアに取り組んでいます。メインクラスが1つあり、serverこれは明らかにサーバーインスタンスを表します。

インスタンスはリクエストを送信でき、serverユーザーにはコールバックによってレスポンスが通知されます。

コードは次のようなものです。

class server
{
  public:
    typedef boost::function<void (int duration)> callback_func;

    void send_request(endpoint& ep, callback_func cb);
};

ここで、コールバックを呼び出したインスタンスについて知りたいユーザーとして、次のことができるとしましょう。

void mycallback(const server& sv, int duration) { ... }

server sv;
sv.send_request("localhost", boost::bind(&mycallback, boost::ref(sv), _1));

しかし、私は疑問に思います:そうすることで何かオーバーヘッドはありますか?通話mycallbackは「通常の」通話を使用するよりも遅くなりますか?

ありがとうございました。

脚注:もちろん、次のように変更することもできtypedefます。重大なオーバーヘッドが発生したtypedef boost::function<void (const server& sv, int duration)> callback_func;場合は、おそらくそれを最終的に実行します。boost::bindの使用を意味するコストを知りたいだけですboost::bind

4

4 に答える 4

5

もちろん、それはオーバーヘッドを引き起こします。それが行うことは、バインドされたパラメーターを格納operator()し、残りの引数で呼び出すファンクターを作成することです。さて、これは重要ですか?それはただの言葉なので、私にはわかりません。1000万件のリクエストを行い、それを測定します。このオーバーヘッドがあなたにとって重要であるかどうかを判断できるのはあなただけです。

また、私も同様の問題に直面しました。デリゲートは本当に必要なかったので、関数ポインターを使うことができました。しかし、いくつかの代替実装についても言及している興味深いベンチマークboost::functionを見つけました。それらはすべて、よりも優れたパフォーマンスを備えています。これには、移植性と、場合によっては実装における醜い非標準のハッキングが犠牲になります(ただし、見返りとしては非常に優れたパフォーマンスが得られます)。

于 2011-05-05T08:55:25.667 に答える
5

boost::bind関数テンプレートへの引数として使用される場合に最適化できる関数オブジェクトを生成しますがboost::function、関数へのポインターを渡すとそのインライン化が妨げられるのと同様に、この最適化が妨げられます。boost::functionそれ自体は、仮想関数allよりも多くのオーバーヘッドを導入したり、関数へのポインターを介して呼び出す必要はありません。

PS。TamásSzeleiに同意します。1,000万件のリクエストを行い、それを測定します。

于 2011-05-05T09:01:55.357 に答える
2

通常の関数呼び出しと比較すると、関数呼び出しには2つの間接費がかかります。これは、(非仮想化されていない)仮想関数呼び出しのオーバーヘッドに似ています。

最初の間接参照は、boost :: functionで発生する型消去によるものです(これはドキュメントに記載されていboost::functionます)。これは実際には最適化できず、裸の関数ポインタでも同じペナルティがあります。

2番目の間接参照はmycallback、関数ポインターを介して関数を呼び出すことから発生します。非常によく最適化されたコンパイラーはこれを理解して最適化できますが、通常のコンパイラーはそうしません。mycallback関数オブジェクトに変換すると、(すべてのコンパイラで)この間接参照を取り除くことができます。

それ以外の

void mycallback( .1. ) { .2. }

あなたがやる

struct mycallback {
    void operator()( .1. ) const { .2. }
};
于 2011-05-06T19:44:15.767 に答える
1

boost::bindはファンクターのコピーを引き起こすことに注意してください。これは非常に重要です。私のオペレーティングシステムのニュースと削除は非常に高価です。ref()およびcref()に関するboost::bindのドキュメントを参照してください。メンバー関数もファンクターのコピーを引き起こすと思いますが、それに関するドキュメントはありません。

于 2012-07-05T09:10:12.710 に答える