Подтвердить что ты не робот

Закрытие вызовов debug() в if isDebugEnabled(): хорошая политика?

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

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

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

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

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

Считаете ли вы, что это хорошая политика?

4b9b3361

Ответ 1

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

Смотрите раздел о производительности протоколирования в часто задаваемых вопросах slf4j

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

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

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

Ответ 2

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

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

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

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

Ответ 3

Я согласен со знаменитой цитатой Michael A. Jackson:

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

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

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

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

Ответ 4

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

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

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

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

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

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

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

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

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

Ответ 5

Я думаю, что для того, чтобы написать сообщение с журналом, нужно поставить вызов 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, вы потеряете время. Помните... ваш проект становится больше и ваши сообщения журнала тоже.

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

Ответ 6

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

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