6

C/C++/Objective-C などの言語では、プリプロセッサ マクロを使用して、リリースされたバイナリ用にコンパイルされていないロギング メカニズムを定義するのが一般的です。そのため、パフォーマンス ヒットは発生しません。次のようなもの:

#ifdef DEBUG
printf("some event we want to log\n");
#endif

今、私は Scala にプリプロセッサーがないことを知っています。私の質問は次のとおりです。デバッグ目的でプログラムのアクティビティをログに記録するメカニズムを実装し、オフにしたときにパフォーマンスへの影響を最小限に抑える最良の方法は何ですか?

4

3 に答える 3

15

使用できますscala.annotation.elidable

生成されたコードで呼び出しが削除される可能性があるメソッドの注釈。

-Xelide-below を scalac に渡すと、動作が影響を受けます。アノテーションに与えられた優先度がコマンドライン引数よりも低い場合、省略可能とマークされたメソッドは生成されたコードから省略されます。例:

于 2012-08-20T20:04:06.343 に答える
5

現在 (Scala 2.9.x 以前で) 実践されているのは、サンク タイプを使用することです (たとえば、Simple Logging Facade for Scala SLFSを参照)。

def log(x: =>Any) = if (logging) println(x)

// later in code
log("var1: " + myVar1)

logging文字列の作成 (および後続のアクティビティ) はが true の場合にのみ行われるため、これは多くの場合、文字列を実際に構築するよりもコストがかかりません。ただし、上記のサンクのクロージャ作成のコストは依然として発生しますx

ただし、Scala 2.10.x 以降では、実験的なマクロの実装が標準ディストリビューションに含まれています (このページまたはSIPを参照してください)。loggingマクロ システムを使用すると、(変数チェック以外の) ランタイム コストがほとんどかからないロギング呼び出しを記述できますlog

log("var1: " + myVar1)

になります:

if (logging) log("var1: " + myVar1)

この場合、 に対して作成されたクロージャはなくlog、ロギング メッセージ文字列はloggingが true の場合にのみ評価されることに注意してください。コストは if-check のみです。

于 2012-08-20T19:46:54.897 に答える
1

Log4Jは、一般的な JVM ロギング フレームワークです。パフォーマンスへの影響を最小限に抑えるように特別に設計されています。

JDK 1.3.1 を実行している 800Mhz で動作する AMD Duron では、ロギング ステートメントをログに記録するかどうかを判断するのに約 5 ナノ秒かかります。実際のロギングも非常に高速で、SimpleLayout を使用した場合は 21 マイクロ秒、TTCCLayout を使用した場合は 37 マイクロ秒です。PatternLayout のパフォーマンスは、はるかに柔軟であることを除けば、専用レイアウトとほぼ同じです。

したがって、次のような電話をかけると:

LOG.debug("something here")

フレームワークは、最初に「デバッグ」ロギングが有効になっているかどうかを確認します。このチェックは非常に高速です。ロギングが無効になっている場合、それ以上の作業は行われません。

ただし、問題が 1 つあります。あなたが書くなら

LOG.debug(expensiveOperation())

フレームワークは、コストのかかる操作を実行する前に、デバッグ対応のチェックを行いません。これを修正する方法は、次のように言うことです。

if(LOG.isDebugEnabled) LOG.debug(expensiveOperation())
于 2012-08-20T19:45:23.220 に答える