В log4j, делает проверку isDebugEnabled, прежде чем вход улучшит производительность?

В Visual Studio 2013:

Перейдите: Свойства проекта -> Диспетчер конфигурации -> Общие. Там, в Project Defaults, измените Тип конфигурации на Динамическую библиотеку или Приложение. Нажмите на Применить. Затем вы должны увидеть вкладку Linker, добавленную в меню слева.

191
задан Michael Myers 8 June 2009 в 05:03
поделиться

8 ответов

В данном конкретном случае лучше вариант 1.

Оператор защиты (проверка isDebugEnabled () ) предназначен для предотвращения потенциально дорогостоящих вычислений сообщения журнала, когда он включает вызов методов toString () различных объектов и объединение результатов.

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

Еще лучше использовать более современную структуру ведения журнала, где операторы журнала принимают спецификацию формата и список аргументы, которые должны быть заменены регистратором - но «лениво», только если регистратор включен. Это подход, использованный в slf4j .

229
ответ дан 23 November 2019 в 05:34
поделиться

Если вы используете вариант 2, вы выполняете логическую проверку, которая выполняется быстро. В первом варианте вы выполняете вызов метода (помещаете материал в стек), а затем выполняете логическую проверку, которая по-прежнему выполняется быстро. Я вижу проблему в последовательности. Если некоторые из ваших операторов отладки и информации обернуты, а некоторые нет, это не является согласованным стилем кода. Кроме того, позже кто-то может изменить оператор отладки, включив в него конкатенацию строк, что по-прежнему довольно быстро. Я обнаружил, что когда мы завершили отладку и информацию в большом приложении и профилировали его, мы сэкономили пару процентов производительности. Немного, но достаточно, чтобы потрудиться. Теперь у меня есть пара макросов, настроенных в IntelliJ для автоматической генерации обернутых отладочных и информационных операторов для меня.

0
ответ дан 23 November 2019 в 05:34
поделиться

Это увеличивает скорость, потому что обычно объединять строки в отладочном тексте дорого, например:

boolean debugEnabled = logger.isDebugEnabled();
if (debugEnabled) {
    logger.debug("some debug text" + someState);
}
2
ответ дан 23 November 2019 в 05:34
поделиться

Как уже упоминалось, использование оператора guard действительно полезно только в том случае, если создание строки требует много времени. Конкретные примеры этого: создание строки вызовет некоторую отложенную загрузку.

Стоит отметить, что этой проблемы можно решить, используя Simple Logging Facade для Java или (SLF4J) - http: // www. slf4j.org/manual.html. Это позволяет вызывать такие методы, как:

logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);

Это только преобразует переданные параметры в строки, если включена отладка. SLF4J, как следует из названия, является лишь фасадом, и вызовы регистрации могут быть переданы в log4j.

Вы также можете очень легко «свернуть свою собственную» версию этого.

Надеюсь, это поможет.

6
ответ дан 23 November 2019 в 05:34
поделиться

Вариант 2 лучше.

По сути, это не улучшает производительность. Но это гарантирует, что производительность не ухудшится. Вот как.

Обычно мы ожидаем logger.debug (someString);

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

logger.debug (str1 + str2 + str3 + str4);

и например.

Даже если уровень журнала установлен на ERROR или FATAL, конкатенация строк все же происходит! Если приложение содержит много сообщений уровня DEBUG с конкатенациями строк, это, безусловно, снижает производительность, особенно с jdk 1.4 или ниже. (Я не уверен, выполняются ли более поздние версии jdk internall какой-либо stringbuffer.append ()).

Вот почему вариант 2 безопасен. Даже конкатенации строк не происходит.

6
ответ дан 23 November 2019 в 05:34
поделиться

Использование isDebugEnabled () зарезервировано на случай, когда вы создаете сообщения журнала путем объединения строк:

Var myVar = new MyVar();
log.debug("My var is " + myVar + ", value:" + myVar.someCall());

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

Я лично использую вызовы формата Java 1.5 в классе String следующим образом:

17
ответ дан 23 November 2019 в 05:34
поделиться

Так как в варианте 1 строка сообщения является константой, нет никакого преимущества в переносе оператор журнала с условием, наоборот, если оператор журнала включен отладки, вы будете оценивать дважды: один раз в методе isDebugEnabled () и один раз в debug () метод. Стоимость вызова isDebugEnabled () составляет порядка 5–30 наносекунд, что должно быть незначительным для большинства практических целей. Таким образом, вариант 2 нежелателен, потому что он загрязняет ваш код и не дает никакой другой выгоды.

31
ответ дан 23 November 2019 в 05:34
поделиться

Как @erickson, это зависит. Если я помню, isDebugEnabled уже встроен в метод debug () Log4j.
Пока вы не выполняете дорогостоящие вычисления в своих отладочных операторах, такие как цикл для объектов, выполнение вычислений и объединение строк, на мой взгляд, у вас все в порядке.

StringBuilder buffer = new StringBuilder();
for(Object o : myHugeCollection){
  buffer.append(o.getName()).append(":");
  buffer.append(o.getResultFromExpensiveComputation()).append(",");
}
log.debug(buffer.toString());

будет лучше, как

if (log.isDebugEnabled(){
  StringBuilder buffer = new StringBuilder();
  for(Object o : myHugeCollection){
    buffer.append(o.getName()).append(":");
    buffer.append(o.getResultFromExpensiveComputation()).append(",");
  }
  log.debug(buffer.toString());
}
3
ответ дан 23 November 2019 в 05:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: