12

重複の可能性:
log4j では、ログを記録する前に isDebugEnabled をチェックするとパフォーマンスが向上しますか?

以下の方法で log4j を使用している人を見てきました。

if(logger.isDebugEnabled())
{
    logger.debug(" message ");
}

ただし、logger.debugAPIのドキュメントを確認したところdebug、メッセージをログに記録する前に有効になっているかどうかを確認することがわかりました。その場合、if を余分に書く意味は何ですか?

と書くだけでも全く同じではないでしょうか

logger.debug(" message ");

?

4

6 に答える 6

21

本当に書いてるだけなら

logger.debug(" message ");

それでは何のメリットもありません。ただし、次のことを考慮してください。

logger.debug("This: " + message + " happened on thread " + thread +
            "because " + cause);

結果が破棄されるだけの場合、その文字列連結 (および潜在的によりコストのかかる変換 -ログに記録したいが、文字列に変換するのにコストがかかるものについて考えてください) を実行したくありません。

通常のケースでロギングがパフォーマンスに重大な影響を与える場合、それは、突然診断をオンにしたい状況で本当に役立つロギング コードを追加する意欲をそぐものです。

于 2012-11-07T10:48:29.730 に答える
7

ここでのアイデアは、パラメーターの評価を防ぐことだと思います-あなたの場合は簡単ですが、たとえば、次のようなものだとしましょう:

logger.debug("Foo" + bar() + " bar: " + foo());

これは不自然ですが、デバッグが有効になっていない場合は、bar()andfoo()と文字列の連結を実行したくない場合があります...

于 2012-11-07T10:48:30.363 に答える
2

理由の 1 つは、メッセージの作成に多少のオーバーヘッドがあるためです。例えば:

if(debug.isDebugEnabled()) {
    String message = buildLogMessage()
    logger.debug(message);
}

実行に時間がかかる場合buildLogMessage()は、出力がログに記録されないことがわかっているときに実行したくない場合があります。

ただし、これを解決するより良い方法は、 を使用してObjectRender、値がログに記録される場合にのみ String への変換が行われるようにすることです。

于 2012-11-07T10:50:35.287 に答える
1

少し時間をとって log4j の実装を確認すると、その理由がわかります。書くとき: logger.debug(" message ");log4j アペンダーは常に loggingEvent を追加します。それは高価な変換です。if 条件が最適ですが、場合によっては便利です。

// AppenderAttachableImpl.class
public int appendLoopOnAppenders(LoggingEvent event) {
        int size = 0;
        if (appenderList != null) {
            size = appenderList.size();
            for (int i = 0; i < size; i++) {
                Appender appender = (Appender) appenderList.elementAt(i);
                appender.doAppend(event);
            }

        }
        return size;
    }
于 2012-11-07T10:57:29.377 に答える
1

もう 1 つの理由は、HotSpot VM の動作を変更することです。どのように機能するかはよくわかりませんが、本番モードで実行している場合 (デバッグ ログがオフ)、HotSpot VM は、if ステートメントと内部のすべてがそこにないかのようにコードを最適化する必要があります。

于 2012-11-07T13:08:30.750 に答える
0

デバッグ メソッドが呼び出される前に、文字列の連結など、条件文で回避できるコードが実行される可能性があります。例:

log.debug("Value of variable1:"+variable+" Value of variable2:"+variable2);

条件 if log.isDebugEnabled() を追加すると、文字列連結は実行されません。

それが唯一の利点です。

于 2012-11-07T10:49:31.617 に答える