21


5

私たちのチームは、ロギングをするようなポリシーを持っています。

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

単純に次のようにloggingメソッドを呼び出すのではありません。

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

このやり方は パフォーマンスの向上につながる可能性がありますが、その一方でそれはコードベースをより複雑にします。 私たちのアプリケーションはパフォーマンス上の問題を抱えていませんし、おそらくそうすることもありません。ポリシーを導入するための議論は単にそれが良い習慣であるということだったので、ロギングをするたびに使われます。

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

6 Answer


26


あなたは_SLF4J_を使い、_log4j_をあなたの実装にするべきです。 _SLF4J_を使用すると、パラメーター化されたメッセージを使用して、 `+ isDebugEnabled()+`を完全に排除できます。

slf4j FAQのhttp://www.slf4j.org/faq.html#logging_performance [ロギングパフォーマンスに関するセクション]を参照してください。

_ _ 次の2行はまったく同じ出力になります。 ただし、無効になっているログ記録ステートメントの場合、2番目の形式は最初の形式よりも少なくとも30倍優れています。

+ logger.debug("新しいエントリは "+エントリ+"。 "); +

+ logger.debug("新しいエントリは{}。 "、entry); + _ _


18


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

  • 多くの作業が文字列の構築に入る必要があります(例: それはルックアップをするか、または非常に小さな断片から非常に大きな文字列を構築する必要があります。

  • それは他の多くの仕事をしていない(しかし頻繁に呼ばれる)ループにあるので、単純なログ文字列でさえ構築するのに費やされた時間の_比例_はより高いです

それは包括的なルールではありません、そして、私はこれらの状況の両方が「比較的」まれであると思います。

もちろん、私たちが本当に欲しいのは、「デバッグメソッドを呼び出すことです。デバッグ文字列自体ではない引数を渡しますが、デバッグ文字列をビルドする方法を知っているものです。必要。"簡潔なクロージャーがなければ、これはJavaでは見苦しいでしょう。 (ラムダ式の形式のクロージャを持つ言語でも、言語がそのキャプチャをどのように処理するかによっては、関連する変数をキャプチャすることが状況によっては重要になる可能性があります。)


7


私はhttp://en.wikiquote.org/wiki/Michael_A._Jackson [Michael Aの有名な引用に同意します。 ジャクソン]:

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

プログラム最適化の2番目のルール - 専門家のみのために:まだそれをしないでください。 _ _

私は、ほとんどの場合、パフォーマンスの向上が顕著で顕著になることを確認せずにコードベースをより複雑にする価値はないと思います。

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


2


私はその参照をオンラインで見つけることができない(おそらく本でそれを読む)が、画面に文字列を書いたBIOS呼び出しの例があった。

スクリーンに文字列を書いたコードは、文字列がスクリーンからはみ出していないことを確認するためにチェックしてから、スクリーンに文字を書き出す関数を呼び出しました。

画面に文字を書き込んだ関数は、文字が画面の外に書き込まれないことを確認するためにチェックしました。

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

したがって、高レベルでチェックして低レベルでのチェックを回避できれば、作業を大幅にスピードアップできます。

あなたが提供する場合、コードがループの中にあるか、またはたくさんのロギングステートメントがあるならば、あなたがそうするので明らかな利益があるでしょう:

  • 文字列の作成(および関連するGC)を削除します

  • ifステートメントの数を減らします(ただし、ホットスポットでは最適化される可能性が非常に高いです)。

私は一般的に言って、簡単な回避策があるならば、あなたは高価であると知られている何かを追加するべきではありません。 これは明らかにその場合に当てはまります - ifステートメントを追加することは難しくありません、後で入れることは苦痛であり、そしてそれは明確なスピード/メモリ改善を提供します。

この最適化と時期尚早の最適化との違いは、これは常にコストがかかることがわかっているということです。したがって、問題はプログラムに追加する累積コストかどうかです。 コストはほぼ一定で、コードを書いた時点で知られています。


1


ログメッセージを書く前に、isDebugEnabled()呼び出しを行った方が良いと思います。 あなたが簡単に後でログメッセージを更新することができます。 ログメッセージをより柔軟にするために、次のコードを使用します。

";(LOGGER.isDebugEnabled()){String msg ="メッセージ{0}に{1}個の差分オブジェクトを{2}に配置できます。 "; // $ NON-NLS-1 $ Object [] args = new Object [] {file1.toString()、new Integer(23)、anObject}; LOGGER.debug(MessageFormat.format(msg、args)); }

あなたがif文を持っていないだろうときあなたは時間を失うことになります。 覚えている… プロジェクトが大きくなり、ログメッセージも大きくなります。

ログメッセージはあなたのコードを遅くしてはいけません!


0


「モデル」がすでに知られている場合は、それを記録するだけではそれほど高価ではありません。 しかし、以下のように「モデル」をロギングのためだけに取得する必要がある場合は、単純さが損なわれる可能性があります。

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