コンパイル時定数を関数に与える方が良い方法はありますか?関数の引数とテンプレートのパラメータ

コード全体でいくつかの場所でロギング機能が呼び出されています。すべてのログに、 2コンパイル時定数を指定する必要があります。達成するには2つのアプローチがあります:

(1) Function argument:

template
void log (const T &obj, const int LINE, const int COUNT)
{
 //T is used for some purpose
  if(debug)
    logging(obj.out(), LINE, COUNT);
}

それを、

log(str, __LINE__, __COUNTER__);

(2) Template parameter:

template
void log (T &obj)
{
 //T is used for some purpose
  if(debug)
    logging(obj.out(), LINE, COUNT);
}

それを、

log<__LINE__, __COUNTER__>(str);

私は決めることができません。第1のアプローチはシンプルさを提供するためですが、コンパイル時には一定の時間を過ごしています。 2番目のアプローチは完璧ですが、コンパイル時間はおそらく増加します。この作業は面倒ですが、まだ実装していないので、ベンチマークはありません。

誰かが自分の経験や知識からこれに答えることができれば、大きな助けになるでしょう。

6
@NicolBolas、私はコンパイル時間とランタイムに基づいて2の中からより良いものを選択したいと思うので。また、サンプルコードに若干の変更が加えられています。
追加された 著者 iammilind,
どのように「より良い」と定義していますか?両方とも作業するので、どちらか一方が他のものより優れていると言うためにどの基準を使用しますか?
追加された 著者 Nicol Bolas,
どのような logging 関数でも、引数として2つの整数を渡すよりも遅くなることが最も確かです。だから私はどのようにランタイムのパフォーマンスがどちらかの方法で非常に変化するかはわかりません。これは時期尚早の最適化のような疑いがあると思われます。
追加された 著者 Nicol Bolas,
@Nichol:「引数として2つの整数を渡すよりも、確かに遅くなるでしょう」 - debug が偽であるとは思えません。もちろん、それはまだ無視できる程度です。
追加された 著者 Steve Jessop,

2 答え

これらの2つの間の選択が呼び出しコードと異なるので、私はマクロを介してロギングすることを推奨します。そうすれば、これらの間で切り替えるのが簡単だから、どちらが良いか心配する必要はありません。

実際のアプリケーションを作成したら、マクロ定義を混乱させて2つを比較することができます。最適化する生産的な領域があれば、そうではありません。大きな違いを生むことが判明した場合は、 -DLOGGING_COMPILES_QUICKLY -DLOGGING_RUNS_QUICKLY のどちらを使用するかを決定するためにビルド設定を開いたままにすることもできます。

マクロのもう1つのメリット: debug がtrueの場合にのみ、最初の引数が評価されるように調整できます。私は str のインターフェイスが何であるか、それらのオブジェクトがどこから来たのかわかりませんが、 log に渡すために、 log はデバッグ以外の場合にはそれを使用しません。それは実行時に無駄になる可能性があります。

4
追加された
Nice answer ... LINE&COUNTのほとんどは使用されません。どのような代替は、その場合には、生産コードのモップですか?
追加された 著者 iammilind,
@iammilind: debug がコンパイル時定数で、 log の呼び出しがインライン化されている場合、発行されたコードはおそらくどちらの方法でも同じであるはずですが、問題。特定の実装の詳細を知りたい場合は、逆アセンブリを確認してください。
追加された 著者 Steve Jessop,

私は最初の選択肢に行くだろう。 2つの整数を渡すことによるパフォーマンスへの影響はごくわずかです。オプティマイザは関数呼び出しをインライン化することもありますが、その場合は両者の間に違いはありません。私が考える第二の選択肢は、悪い考えです。何故ならば、同じ関数のバージョンをたくさん作成するからです。

3
追加された
まあ、最初のログ関数のいくつかのバージョン、std :: string、std :: wstring、char *、wchar_t *しか存在しません。基本的には、2番目のバージョンへのすべての関数呼び出しは新しい関数になります。オプティマイザはおそらくそれを処理しますが、コンパイル時間が長くなると同じ結果になります。
追加された 著者 ronag,
質問の構文に若干の変更があります。 log 自体は template 関数ですが、私はそれを言及していないと思っていました。また、コンパイラは template log のいくつかのバージョンを最適化しませんか?
追加された 著者 iammilind,