Sorrounding Logger с условием If, чтобы избежать избыточной конструкции String - PullRequest
6 голосов
/ 10 января 2010

Я получил рекомендацию использовать этот синтаксис при входе в Java:

if (logger.isLoggable(Log.FINE))
{
    logger.fine("bla"+" bla"+" bla");
}

Причина этого заключается в том, чтобы избежать создания избыточной строки параметров, если уровень ведения журнала ниже, чем «FINE». (в приведенном выше примере - 5 избыточных строковых объектов. («bla» X3, «bla bla» и «bla bla bla»).

Мне бы хотелось услышать, что другие делают по этому поводу, или если вы считаете, что это вообще необходимо.

Спасибо !!

Ответы [ 4 ]

6 голосов
/ 10 января 2010

Некоторые более новые каркасы ведения журналов позволяют указывать аргументы в качестве параметров и не будут оценивать их, если нет ведения журнала.

Пример, который я нашел, - это LogBack, преемник Log4j. Вот информация: http://www.infoq.com/news/2007/08/logback

Это дает вам лучшее из обоих миров, так сказать. Элегантный синтаксис, но хорошая производительность.


Пример кода Log4j:

if( logger.isDebugEnabled() ) {
  logger.debug( "User with account " + 
    user.getAccount() + " failed authentication; " +
    "supplied crypted password " + user.crypt(password) +
    " does not match." );
}

Эквивалентный LogBack код:

logger.debug( "User with account {} failed authentication; " +
    "supplied crypted password {} does not match.",
    user.getAccount(), user.crypt(password) );

Откладывает стоимость сборки сообщения до тех пор, пока LOGBack не установит, будет ли это сообщение просматриваться или нет. Это не откладывает затраты на получение дорогих параметров, таких как шифрование пароля в приведенном выше примере.

0 голосов
/ 10 января 2010

Это улучшение (хорошо), но его можно немного улучшить.

Установите окончательные флаги для каждого уровня ведения журнала (FINE и т. Д.) В глобальном объекте, используемом в качестве config, затем используйте StringBuffer для создания выходных данных отладки - вы даже можете одновременно форматировать числа в потоке.

public class MyAppConfig {
  public final boolean FINE=true;
  // ... other fields
}

public class MyApp {
  void someFunction() {
    ...
    int imagesProcessed;
    imagesProcessed = processImages();

    if (MyAppConfig.FINE) logger.fine(new StringBuffer(35).
      append("Count of images processed: ").append(imagesProcessed).toString());

    ...
  }
}

Здесь строковый буфер настроен с «начальной емкостью» 35 символов. Если вы знаете, сколько символов будет сгенерировано, вы можете предоставить подсказки для StringBuffer.

0 голосов
/ 10 января 2010

Абсолютно необходимо для регистрации типа отладки. Примерно в 10 раз быстрее проверить уровень журнала, чем создать строку и выбросить ее.

0 голосов
/ 10 января 2010

Строковые объекты являются неизменяемыми, поэтому повторное объединение является дорогостоящей операцией. Требуется повторное выделение памяти, создание объекта и итерация. Учитывая, что некоторые вызовы журналирования на более тонких уровнях журналирования могут вызываться тысячи или миллионы раз в минуту, это может быть значительным приростом производительности, как показано на рисунке. Хотя для небольших приложений это может не стоить дополнительных усилий.

В качестве примечания: Вы можете сохранить еще большую производительность, где это действительно важно, используя такую ​​константу, как эта:

public static final boolean DEBUG = false;

Если вы теперь поместите код регистрации в блок if, такой как этот, JVM сможет полностью оптимизировать вызовы отладки при работе в режиме продукта. Это так же близко к C # ifdef.

if (Globals.DEBUG) {
    // Logging call
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...