私はイベント駆動型アプリケーションを持っています。 EventSource
が( - コンパイル時に特異的に)変更すること可能にしながら - 私は、イベントハンドラ(多くの/すべてのイベントの可能EventHandler
クラス)一般的な実装を維持したいです。カップルへC++での待ち時間の短いコールバック
EventSource
とEventHandler
、私はEventSource
内ハンドラのインスタンスを格納する必要があります。私は、ハンドラ様々な形態のを格納しようとした:EventHandler
の界面に
- ポインタ(すなわち、コンクリートで定義されたパブリック・ハンドラメソッドを有する
EventHandler
のstd::function
の - インスタンス - これは最大の柔軟性
しかし、どちらの場合も、ターゲットメソッド/ラムダを呼び出す際の待ち時間が(約250ns私のテスト・セットアップに)かなり高かった - と悪いことに、矛盾した仮想テーブルおよび/またはヒープ割り当てが原因である可能性があり、および/または。タイプ消去?
この待ち時間を短縮するために、私は、テンプレートを利用することにしたいです。
私が思い付くことができる最高は次のとおりです。
template <typename EventHandler>
class EventSource1
{
EventHandler* mHandler;
public:
typedef EventHandler EventHandlerType;
void AssignHandler (EventHandler* handler)
{
this->mHandler = handler;
}
void EventuallyDoCallback (int arbArg)
{
this->mHandler->CallbackFunction (arbArg);
}
};
template <EventSourceType>
class EventSourceTraits
{
typedef EventSourceType::EventHandlerType EventHandlerType;
static void AssignHandler (EventSourceType& source, EventHandlerType* handler)
{
source.AssignHandler(handler);
}
};
class EventHandler
{
public:
void CallbackFunction (int arg)
{
std::cout << "My callback called\n";
}
};
int main()
{
EventSource1<EventHandler> source; /// as one can notice, EventSource's need not to know the event handler objects.
EventHandler handler;
EventSourceTraits<EventSource1>::AssignHandler (source, &handler);
}
このメソッドは、すべて私のEventSource
年代は、テンプレートクラスなるように制限を課します。
質問::コールバックに一貫性のある低遅延を実現するための最良の方法はありますか?このコードを改善して、イベントソースクラスがイベントハンドラオブジェクトの型から完全に独立しないようにすることはできますか?
あなたは待ち時間があれば何であるか試してみたことがありますか?待ち時間が実際に呼び出され、他のエフェクトが適用されないかどうか(例:インスタンス化されるオブジェクト、評価するディスパッチャコード、お互いにロックするスレッド、またはこれまでのものなど)を調べるだけです。 –
通常のメンバではない関数への単純な未使用のポインタを最初に試してみてください。それを上回ることはできません。あなたがそのパフォーマンスを受け入れることがわかったら、あなたは戦うチャンスがあります。仮想呼び出しは、本質的に関数ポインタと同じ性能を持つはずです。あなたは本当のプロファイリングをしましたか? –
@StephanLechnerは、良く知られているオブジェクトのよく知られているメンバ関数です。一貫して<30nsを要します。 仮想通話には約60nsかかりますが、一貫しています。 どちらも一致していてもかまいません。私はテンプレートで上記のコードと同様の動作を取得します。 p.s.私はどんな種類のプロファイリングもしていない。 – rat6