2017-09-14 7 views
4

Javaでパラメータ化されたログを読み込んでいましたが、遅延評価を実行するときに連結の代わりにパラメータ化されたログを使用すると言われています。パラメータ化されたログを使用する理由を理解できない

ので、代わりの

logger.debug("My text is" + x); 

使用:トレースレベルのみの情報のログに設定されている場合

logger.debug("My text is {}", x); 

、なぜ連結は、最初のシナリオで起こるのでしょうか?

logger.debug("My text is {}",() -> compute()); 

代わりに、この場合

logger.debug("My text is {}", compute()); 

の、なぜラムダ方法がより良いアプローチと考えられている:私は、ログ内の関数を消費する時間を持っている場合にも、それは使用すると言われている

。文字列連結の場合のように遅く呼び出されることもありませんか?

答えて

9

logger.debug()を入力する前に、パラメータを計算する必要があります。

最初の場合、結果のStringをメソッドに渡す前に、常にString連結を取得します(使用できない場合があります)。パラメータ化されたバージョンでは、連結は行われず、xが渡され、使用されるかどうかが決まります。

compute()と同じです。メソッドを呼び出すには、compute()の結果が必要なので、非ラムダバージョンはメソッドを入力する前に常にcompute()を実行します。

ラムダバージョンは、代わりの方法の結果のパラメータとして(これが要求されたときに方法を実行する実際Supplier方法を通過し、そして必要な場合にのみ実行されます。

+0

詳細な説明をありがとう。関数が呼び出される前に、最初にすべての引数が評価され、次に関数が – user1692342

+2

@ user1692342と呼び出されます。何らかの引数がある場合はyesが返されます。 –

+3

@ user1692342ラムダのアプローチでは、 'compute()'を実行する 'Supplier'としてパラメータを評価することができます。したがって、完全に評価されていますが、実際の 'compute()'メソッドはまだ実行されていません。 – Kayaman

5

アイデアは単純です。通常、アプリケーションは非常に頻繁にロガーを使用しますが、ロギング自体はリソースを消費します。少なくとも、何かをハードドライブに書き込む必要があるからです。あなたの例を見てみましょう:

ロガー設定でINFOレベルがオンになっているとします。その後、コードはこの行を実行し、debug関数に渡すパラメータを評価する必要があります。しかし、debugロガーの内部では、どのログレベルがオンになっているかをチェックし、それはINFOになります。この場合、必要なメッセージは記録しないでください。パラメータ文字列を組み立てるために必要な計算は、時間の無駄とみなされます。 、ログレベルは、メソッドを呼び出す前になった場合、あなたは確認することができ、このような問題を克服するために、この

if (logger.isDebugEnabled()) { 
    logger.debug("My text is " + x) 
} 

ようにあなたが唯一これは必須ですメッセージを組み立てますので、それは良くなるが、ここでの問題はlogger.isDebugEnabled()が二度評価さという点です。まずコードの中に入れてからlogger.debug()の中に入れます。 これは、パラメータ化されたロギングが示唆された理由です。 ラムダが提案した時間のかかる操作にも同じことが当てはまります。それがあなたのために少し助けてくれることを願っています!

1

これは、Optional.orElse()Optional.orElseGet()とほとんど同じことですが、2番目のものは必要なときにのみ呼び出されます。

私はロガーが内部的にこのような何かをチェックすることを前提としてい

if(logLevel.isDebug()){ 

     Value v = supplier.get(); 
     // log v 
} 

は(DB callのように)あなたのラムダは、その値を計算するために、いくつかの重いコールを使用したと、あなたは確かにすべてのを算出している必要はありません必要な場合にのみ、の時刻。

関連する問題