情報をトレースするためにslf4jを使用しています。私のコードは
private static final Logger log = LoggerFactory.getLogger(ObjectTest.class);
log.trace("Time taken to store " + count
+ " objects of size " + size + " is " + (time) + " msecs");
log.trace("Time taken to store {} objects of size {} is {} msecs",
new Object[] { count, size, time });
log.trace("Time taken to store {} objects of size {} is {} msecs",
count, size, time);
トレースを記録するための好ましいメカニズムです。
3が最高です。
3と2は同じ(またはほぼ同じ)バイトコードを生成しますが、3は入力が簡単で短いため、3は2よりも優れています。
トレースが有効になっていない場合、1は文字列の連結(「保存にかかる時間」+カウント+ ....)を実行する必要がありますが、2はトレースが有効な場合にのみ文字列の連結を行います。 1。
3は、SLF4J 1.6.xでサポートされていないことを除いて最適です。 3つ以上の引数の場合、2番目の形式が必要です。 3番目の形式は、1つまたは2つの引数でのみ機能します(3つ以上ではありません)。
SLF4J 1.7の時点で、3番目の形式も3つ以上の引数でサポートされるようになりました。 Javaコンパイラは、3つ以上の引数を持つ呼び出しを2番目のフォームにサイレントに変換し、Object []を印刷メソッドに渡します。これは、Javaこれにより、SLF4J 1.7はSLF4J 1.6と100%互換になります。
3番目のバリアントが最適です。
実際、最初のケースは、StringBuilderによる文字列の連結です。
2番目と3番目のケースは同じです。整数値を整数(または他のオブジェクト)にボックス化し、それらをパックする配列を作成する必要があります。
私のマシンでの簡単なテストでは、ロギングが実行されなかった場合(56ns対459ns)の場合、3番目のバリアントの方が約8倍優れていると言われています。
public class LogTest {
private static final Logger logger = LoggerFactory.getLogger(LogTest.class);
public static void main(String[] args) {
int size = 100_000_000;
long start = System.nanoTime();
for (int i = 0; i < size; i++) {
logger.trace("1 {} 2 {} 3 {}", i, i, i);
}
System.out.println((System.nanoTime() - start) / size);
start = System.nanoTime();
for (int i = 0; i < size; i++) {
logger.trace("1 " + i + " 2 " + i + " 3 " + i);
}
System.out.println((System.nanoTime() - start) / size);
}
}