8

私は最近、さまざまな scala ロギング ライブラリを見てきましたが、それらの大部分はロギング機能を次のように実装しています。

def debug(s: => String)

そのため、デバッグ ログをオフにすると、ステートメントは実行されません。ただし、その利点の1つとして具体的に述べているlogulaに出くわしました

多くの Scala ロギング ライブラリとは異なり、Logula はロギング ステートメントに名前渡しセマンティクス (たとえば、f: => A) を使用しません。これは、次の 2 つのことを意味します。

  • Scala コンパイラは、ロギング ステートメントごとに 1 回限りのクロージャ オブジェクトを作成する必要はありません。これにより、ガベージ コレクションの負荷が軽減されます。

これは実際に私にとって完全に理にかなっています。私の質問は、2 つのアプローチを比較する実際のパフォーマンス ベンチマーク/データはありますか? 理想的には、実際のプロジェクトからの何かと、不自然なベンチマークからのものでしょうか?

4

2 に答える 2

8

どちらが速いかは、ユースケースに完全に依存します。静的文字列をログに記録している場合は、その定数文字列を渡して無視する方が高速です。それ以外の場合、文字列を作成する場合は、とにかく少なくとも 1 つのオブジェクトを作成する必要があります。関数オブジェクトは小さくて安価です。文字列を無視する場合は、文字列を作成するよりも関数オブジェクトを作成した方がよいでしょう。

個人的には、この種のトレードオフに関する第一原理の理解は、どちらか一方を使用した可能性のある特定のアプリケーションのケース スタディよりもさらに価値があると思います。常に独自のアプリケーションのベンチマークを行いたいと思うでしょう)。

(注: オブジェクトの作成にかかるコストは、ガベージ コレクターがどれだけ大きな影響を受けるかによって異なります。一般に、存続期間の短いオブジェクトは、1 秒あたり 10 8のオーダーの速度で作成および破棄できますが、これは問題ではありません。ただし、タイトな内部ループを除きます。ロギング ステートメントをタイトな内部ループに配置している場合は、何か問題があると思います。代わりに、そのための単体テストを作成する必要があります。)

于 2012-07-31T16:46:23.430 に答える
3

あえて言いますが、トレードオフに関する哲学的議論は、興味深いトレードオフがある場合に、より有用です。つまり、ここではそうではありません。

class A {
  var debugging = true
  @inline final def debug(msg: => String) = if (debugging) println(msg)

  def f = { debug("I'm debugging!") ; 5 }
}
% scalac292 -optimise a.scala
% ls -l *.class
-rw-r--r--  1 paulp  staff  1503 Jul 31 22:40 A.class
%

閉鎖オブジェクトを数えます。

于 2012-08-01T05:44:02.357 に答える