2017-10-11 12 views
0

いくつかのコンテキスト:効率的な設計

私はいくつかの集中的な計算(ビークルルーティング問題の変動にいくつかの分枝限定アルゴリズム)を実行するC++メソッドを持っています。したがって、このコードでは効率が最も重要です。 私は最適な速度を達成するために別のトリックを試しているので、アルゴリズムの実行中に情報を収集するクラスStatGathererを実装しました(つまり、実現可能なパスはいくつ見つかりましたか? ..)。

void doStuff(const shared_ptr<StatGatherer>& statGatherer = NULL) 
{ 
    //do some stuff 
    ... 

    if (statGatherer != NULL && some unfeasibility condition) 
     statGatherer->countOneFeasiblePath(); 

    //do more stuff 
    ... 

    if (statGatherer != NULL && some bounding criterium on the current path) 
     statGatherer->countOneBoundedPath(); 

    //do more stuff 
    ...  

    if (statGatherer != NULL && a whole path has been found) 
     statGatherer->countOneBoundedPath(); 
    ... 

    //...more information gathering triggered by certain events 
} 

これは十分に機能しますが、上記の擬似コードは数十に実行されるよう皮肉にも、statGathererを含む「プロファイリング」コードのこの種の存在は、アルゴリズムダウンかなり遅くなります:コードは次のようになります何百万回ものstatGathererが提供されておらず、ヌルにデフォルト設定されている場合でも、このコードをまったく持っていないよりもかなり遅いです。

私の質問は次のようなものです。同じコードを持っていないのと比べて、統計を収集する必要がない場合でも効率は損なわれません。

私が考えることができるすべてのテンプレートソリューションは、上記のような実行時チェックを伴うように思われるので、さらに時間がかかります。

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

PS:私はここにいるので、質問をもっと明確にするための建設的なフィードバックを歓迎します。

+0

に使用するコードのインスツルメンテーション:テンプレート引数はStatGatherer*又はダミーポインタ型のいずれかであるていますプロファイリング – user0042

答えて

1

テンプレートStatGathererまたはインラインの何も実装されていない(および参照渡し)タイプの関数をテンプレートにします。コンパイラは、モックでインスタンス化する際に、偽の呼び出しを完全に削除します。

モック方法に対する必要性を回避するが、元からif(statGatherer && ...) statGatherer->...(...);を必要とするポインタを模擬する代替:

template<class T> 
struct dummy_ptr { 
    operator T*() const {return nullptr;} 
    T* operator->() const {return nullptr;} 
}; 
+0

はい - コンパイル時に意思決定をするのはいい考えです。私はそれを推奨するべきではないと思うが、#ifdefと#defineはコンパイル時に意思決定を可能にする。 – mcdowella

+0

vm Davidさん、ありがとう、これはやっているようです。あなたが記述しているものとの違いは、StatGathererクラスがデータメンバーを渡してしまうのを避けるために、私のメインルーチン内のサブルーチンによって実際に呼び出されるためです。 StatGathererがダミークラスの場合、オーバーヘッドは実際には実質的に消えてしまいます。 コンパイラを幸せにするだけのダミーコードを書く必要のない解決策を聞いてもうれしいです。 – GloomyJul

関連する問題