2009-03-17 1 views
18

私たちのチームではなく、単にこのようなログメソッドを呼び出すisDebugEnabled()の場合、debug()への呼び出しを囲みます:良いポリシーですか?

if (LOGGER.isDebugEnabled()) { 
    LOGGER.debug("model[" + model + "]"); 
} 

のようなログインを行う方針を持っています

LOGGER.debug("model[" + model + "]"); 

この慣行は、いくつかのperformance improvementにつながるすることが可能であるが、一方でコードベースが複雑になります。 私たちのアプリケーションにはパフォーマンス上の問題はなく、おそらく決してありません。ポリシーの導入の議論は単にそれが良い方法であるため、ログを記録するたびに使用されることになります。

あなたはそれが良い政策だと思いますか?

答えて

7

私はMichael A. Jacksonの有名な言葉に同意する:

プログラムの最適化の最初のルール:それをしないでください。

プログラム最適化の第2のルール - 専門家のみ:それはまだやめましょう。

多くの場合、パフォーマンスの向上が顕著/顕著になることを確信することなくコードベースを複雑にする価値はないと思います。

私はパフォーマンスの向上について認識していますが、個々のプログラマが特定のケースで余分なコード行を追加する必要があるかどうかを判断する責任があると思います。ほとんどの場合、余分な行はパフォーマンス面で目に見えない利益をもたらすことなく複雑さを増やしています。

+1

著者がこの質問をした場合、彼は最適化を実行する必要があることは明らかです。私。コードを最適化するように求められたら、上の2つの引用符で返信しないでください。あなたがどこから来ているのか理解していますが、この状況では役に立たない。私からの –

+0

-1。私はこの "最適化をしないでください"という言葉は嫌いです。もしあなたの最適化*が結果を(たとえ些細なものであっても)得られ、それがほとんど*無料であるならば(これは 'if'文が些細なものです)、複雑ではありません(そして、ちょうど最も些細なことです)、次に進んでそれをしてください。 – bharal

+1

これは不具合を避けるためのチェックリストアクティビティであり、ジュニア開発者に簡単に伝えることができるため、後でデバッグに時間を費やすことになる間違いを間違えないようにしています。 – ammianus

16

構築しているログ文字列が実際にパフォーマンスに大きく影響するような場合は、良い方針です。これは、2つの理由が考えられます。

    作業の多くは、文字列を構築するに行く必要
  • はそれがでます
  • (例えば、それは、検索を行う、または非常に小さな部分のロットからの非常に長い文字列を構築するために持っています)多くの他の仕事をしていません(ただし、非常に頻繁に呼ばれる)ループ、そうであっても、単純なログ文字列を構築費やした時間の割合は高い

それは毛布ルールすべきではないですそして、私はこれらの状況がどちらもと比較的珍しいと予想しています。はまれです。

私たちが本当に望むのは、「デバッグ文字列ではない引数を渡してデバッグメソッドを呼び出すことですが、をビルドする方法を知っているものです。デバッグ文字列それが必要な場合にのみ、必要な場合に限ります」。これは、Javaでは簡潔なクロージャなしでは醜いでしょう。 (ラムダ式のクロージャを持つ言語であっても、言語がキャプチャをどのように処理するかによって、関連する変数をキャプチャすることが重要な場合があります)。

+2

SLFにログメソッドの文字列フォーマットオプションがありませんか? –

+0

私は常に開発者が文字列(パラメータ)を構築するコストについて考える必要がないので、常にこのルールを使用することを推奨します。場合によっては、 'getEntryDebugString()'のような、デバッグログのための特別なパラメータを構築する必要があります。珍しい問題で申し訳ありませんよりも、いくつかの行とエラーが発生しやすいコードを持つ方がよいでしょう。 – xmedeko

0

「モデル」がすでにわかっている場合は、それほど高価ではありません。 しかし、以下のようにロギングのためだけに "モデル"をフェッチする必要がある場合、シンプルさが損なわれる可能性があります。

LOGGER.debug("model[" + proxy.getModel() + "]"); 
1

ログメッセージを書き込む前に、isDebugEnabled()コールを置くことをお勧めします。 後で簡単にログメッセージを更新できます。 次のコードを使用して、ログメッセージをより柔軟にします。

if (LOGGER.isDebugEnabled()) { 
    String msg = "A Message {0} you can put {1} differet Objects in {2}"; //$NON-NLS-1$ 
    Object[] args = new Object[] {file1.toString(),new Integer(23),anObject}; 
    LOGGER.debug(MessageFormat.format(msg,args)); 
} 

if文を使用しないと、時間が失われます。覚えておいてください...あなたのプロジェクトは大きくなり、あなたのログメッセージも大きくなります。

ログメッセージでコードが遅くなることはありません。

+2

メッセージフォーマットに基づいた非常に便利な代替手段、パラメータ化されたメッセージが存在します。 http://www.slf4j.org/faq.html#logging_performance – pisaruk

21

SLF4Jを使用し、log4jを実装する必要があります。 SLF4Jを使用すると、パラメータ化されたメッセージを使用して、isDebugEnabled()を完全に削除することができます。

は、次の2行は、全く同じ出力が得られるsection about logging performance in the slf4j FAQ

を参照してください。ただし、無効なロギングステートメントの場合は、2番目のフォームの方が最初のフォームのパフォーマンスが30倍以上向上します。

logger.debug("The new entry is " + entry + ".");

logger.debug("The new entry is {}.", entry);

+1

文字列の書式設定は、「エントリ」の構築にコストがかかるときに役立ちません。例えば。いくつかの 'logger.debug("新しいエントリは{}です。 "、getEntry());'あなたはgetEntry()がどれほどコストがかかっているかわかりません。 – xmedeko

2

私はオンラインの参照を見つけることができない(おそらく、私は本の中でそれを読む)が、画面に文字を書いたいくつかのBIOSコールの例がありました。

文字列を画面に書き込んだとき、文字列が画面外に出てこないことを確認してから、関数を呼び出して画面に文字を書き出しました。

文字を画面に書き込んだ機能が、文字が画面から書き込まれないことを確認するためにチェックされました。

文字を画面に書き込んだ機能からチェックコードを削除すると、速度が大幅に向上しました。これは、各キャラクターの印刷が非常に頻繁に行われたためです。また、通話前に画面の位置が確認されなかった場合のチェック方法も提供しました。

したがって、高いレベルでチェックでき、低いレベルでのチェックを避けると、大幅にスピードアップできます。あなたが提供する場合

、コードがループしているか、ロギング・ステートメントが多い場合は、あろうから、その後は明らかな利点があるだろうとします

  • は、文字列の作成を削除(および関連するGC)
  • ifステートメントの数を減らします(しかし、ホットスポットはそれらを最適化する可能性が高いですが)。

私は、一般的に、簡単な回避策があれば高価であることが知られているものは追加しないでください。これは明らかにその場合に該当します。if文を追加するのは難しくありません。後で置くのは苦痛であり、速度/メモリの改善が明確です。

私はこれと早すぎる最適化の違いは、これは常にコストがかかることが知られていると考えているので、プログラムに追加したい累積コストかどうかは問題になりますか?コストは非常に一定であり、コードを書く時点で分かっています。

関連する問題