Включение вызовов в debug () в isDebugEnabled (): хорошая политика? - PullRequest
21 голосов
/ 17 марта 2009

Наша команда придерживается политики ведения журнала, как

if (LOGGER.isDebugEnabled()) {  
  LOGGER.debug("model[" + model + "]");
}

вместо простого вызова метода ведения журнала следующим образом:

LOGGER.debug("model[" + model + "]");

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

Как вы думаете, это хорошая политика?

Ответы [ 6 ]

26 голосов
/ 17 марта 2009

Вы должны использовать SLF4J и сделать log4j своей реализацией. С SLF4J вы можете полностью исключить isDebugEnabled(), используя параметризованные сообщения.

См. Раздел о производительности журналов в FAQ по slf4j

Следующие две строки приведут к одинаковому результату. Однако вторая форма будет превосходить первую форму как минимум в 30 раз в случае отключенного оператора ведения журнала.

logger.debug("The new entry is " + entry + ".");

logger.debug("The new entry is {}.", entry);

18 голосов
/ 17 марта 2009

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

  • Требуется много работы для построения строки (например, она должна выполнять поиск или создавать очень большую строку из множества очень маленьких кусочков)
  • Он находится в цикле, который не выполняет много другой работы (но вызывается очень часто), поэтому доля времени, потраченного на создание даже простой строки журнала, выше

Это не должно быть общим правилом, и я ожидаю, что обе эти ситуации будут относительно редкими.

Конечно, мы действительно хотим иметь возможность сказать: «Вызовите метод отладки, передав аргумент, который не является самой строкой отладки, но является чем-то, что знает, как построить строка отладки, если и только если это необходимо. " Это было бы ужасно в Java без кратких замыканий. (Даже в языке с замыканиями в форме лямбда-выражений захват соответствующих переменных может быть значительным в некоторых ситуациях, в зависимости от того, как язык обрабатывает захват.)

7 голосов
/ 17 марта 2009

Я согласен с известной цитатой Майкла А. Джексона :

Первое правило оптимизации программы: не делайте этого.

Второе правило оптимизации программы - только для экспертов: пока не делайте этого.

Я думаю, что в большинстве случаев не стоит делать более сложную кодовую базу, не будучи уверенным, что прирост производительности будет заметным / значительным.

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

2 голосов
/ 17 марта 2009

Я не могу найти ссылку в Интернете (возможно, я прочитал ее в книге), но был пример некоторого вызова BIOS, который записал строку на экран.

Код, который записал строку на экран, проверил, чтобы убедиться, что строка не исчезнет с экрана, а затем вызвал функцию для записи символа на экран.

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

Удаление проверочного кода из функции, которая записывает символ на экран, привело к значительному увеличению скорости. Дело в том, что печать каждого символа происходила очень часто. Они также предоставили метод, который проверял случаи, когда положение экрана не проверялось до вызова.

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

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

  • удалить создание строки (и связанный GC)
  • уменьшить количество операторов if (хотя горячая точка, скорее всего, их оптимизирует).

Я бы сказал, что в общем случае вам не следует добавлять что-либо, что, как известно, является дорогостоящим, если есть легкое обходное решение. Это явно относится к этому случаю - добавление оператора if не сложно сделать, его трудно добавить позже, и оно обеспечивает определенное улучшение скорости / памяти.

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

1 голос
/ 17 марта 2009

Я думаю, что имеет смысл сделать вызов isDebugEnabled () до того, как вы напишите свое сообщение журнала. Чем вы можете легко обновить свое сообщение журнала позже. Мы используем следующий код, чтобы сделать сообщения журнала более гибкими.

if (LOGGER.isDebugEnabled()) {  
  String msg = "A Message {0} you can put {1} differet Objects in {2}"; //$NON-NLS-1$
  Object[] args = new Object[] {file1.toString(),new Integer(23),anObject};
  LOGGER.debug(MessageFormat.format(msg,args));
}

Если у вас не будет заявления if, вы потеряете время. Помните ... ваш проект становится больше, и ваши сообщения журнала тоже.

Журнал сообщений не должен замедлять ваш код!

0 голосов
/ 17 марта 2009

Если «модель» уже известна, то просто ведение журнала не так уж и дорого. Но, если «модель» должна быть выбрана только для регистрации, как показано ниже, простота может быть поставлена ​​под угрозу.

LOGGER.debug("model[" + proxy.getModel() + "]");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...