Я использую Log4J в моем приложении для регистрации. Ранее я использовал отладочный вызов, как:
Опция 1:
logger.debug("some debug text");
но некоторые ссылки предполагают, что лучше isDebugEnabled()
сначала проверить , например:
Вариант 2:
boolean debugEnabled = logger.isDebugEnabled();
if (debugEnabled) {
logger.debug("some debug text");
}
Поэтому мой вопрос: « Улучшает ли вариант 2 производительность каким-либо образом? ».
Потому что в любом случае у каркаса Log4J такая же проверка на debugEnabled. Для варианта 2 может быть полезно, если мы используем несколько операторов отладки в одном методе или классе, где каркасу не нужно вызывать isDebugEnabled()
метод несколько раз (при каждом вызове); в этом случае он вызывает isDebugEnabled()
метод только один раз, а если Log4J настроен на уровень отладки, то фактически он вызывает isDebugEnabled()
метод дважды:
- В случае присвоения значения переменной debugEnabled и
- На самом деле вызывается методом logger.debug ().
Я не думаю, что если мы напишем несколько logger.debug()
операторов в методе или классе и вызываем debug()
метод в соответствии с вариантом 1, тогда это накладные расходы для каркаса Log4J по сравнению с вариантом 2. Поскольку isDebugEnabled()
это очень маленький метод (с точки зрения кода), он может быть хорошим кандидатом на встраивание.
toString()
только при необходимости.Так как в варианте 1 строка сообщения является константой, нет абсолютно никакой выгоды в обёртывании оператора ведения журнала условием, напротив, если в операторе журнала разрешена отладка, вы будете выполнять оценку дважды, один раз в
isDebugEnabled()
методе и один раз вdebug()
метод. Стоимость вызоваisDebugEnabled()
составляет порядка 5–30 наносекунд, что для большинства практических целей должно быть незначительным. Таким образом, вариант 2 нежелателен, потому что он загрязняет ваш код и не дает никакой другой выгоды.источник
Использование
isDebugEnabled()
зарезервировано для того, когда вы создаете сообщения журнала путем объединения строк:Однако в вашем примере выигрыш в скорости отсутствует, поскольку вы просто регистрируете строку и не выполняете такие операции, как конкатенация. Поэтому вы просто добавляете в свой код раздувание и усложняете его чтение.
Я лично использую вызовы формата Java 1.5 в классе String следующим образом:
Я сомневаюсь, что есть много оптимизаций, но это легче читать.
Обратите внимание, что большинство API-интерфейсов ведения журналов предлагают форматирование «из коробки»: slf4j, например, обеспечивает следующее:
который даже легче читать.
источник
В Java 8 вам не нужно использовать
isDebugEnabled()
для повышения производительности.https://logging.apache.org/log4j/2.0/manual/api.html#Java_8_lambda_support_for_lazy_logging
источник
Короткая версия: Вы также можете выполнить логическую проверку isDebugEnabled ().
Причины:
1- Если сложная логика / конкат строки. добавлен к вашему заявлению отладки, у вас уже будет проверка на месте.
2. Вам не нужно выборочно включать оператор в «сложные» отладочные операторы. Все заявления включены таким образом.
3- Вызов log.debug выполняет перед регистрацией следующее:
if(repository.isDisabled(Level.DEBUG_INT))
return;
Это в основном то же самое, что журнал вызовов. или кот. isDebugEnabled ().
ТЕМ НЕ МЕНИЕ! Это то, что думают разработчики log4j (как и в их javadoc, и вы, вероятно, должны пойти по этому пути).
Это метод
Это Javadoc для него
источник
Как уже упоминалось, использование оператора guard полезно только в том случае, если создание строки требует много времени. Конкретные примеры этого - при создании строки будет запускаться ленивая загрузка.
Стоит отметить, что этой проблемы можно избежать, используя Simple Logging Facade для Java или (SLF4J) - http://www.slf4j.org/manual.html . Это позволяет вызывать методы, такие как:
Это только преобразует переданные параметры в строки, если включена отладка. SLF4J, как следует из его названия, является лишь фасадом, и вызовы регистрации могут передаваться в log4j.
Вы также можете очень легко «свернуть свою» версию этого.
Надеюсь это поможет.
источник
Вариант 2 лучше.
По сути, это не улучшает производительность. Но это гарантирует, что производительность не ухудшается. Вот как.
Обычно мы ожидаем logger.debug (someString);
Но, как правило, по мере того, как приложение растет, многие переходят из рук в руки, особенно начинающие разработчики.
logger.debug (str1 + str2 + str3 + str4);
и тому подобное.
Даже если для уровня журнала установлено значение ERROR или FATAL, конкатенация строк происходит! Если приложение содержит много сообщений уровня DEBUG с конкатенацией строк, то это, безусловно, требует снижения производительности, особенно с jdk 1.4 или ниже. (Я не уверен, что в более поздних версиях jdk internall есть какой-либо stringbuffer.append ()).
Вот почему Вариант 2 безопасен. Даже конкатенации строк не происходит.
источник
Как @erickson это зависит. Насколько я помню,
isDebugEnabled
ужеdebug()
встроен метод Log4j.Пока вы не выполняете дорогостоящих вычислений в своих операторах отладки, таких как циклы над объектами, выполняете вычисления и объединяете строки, на мой взгляд, все в порядке.
было бы лучше как
источник
Для одной строки я использую троичную часть внутри сообщения регистрации. Таким образом, я не делаю конкатенацию:
EJ:
Я делаю:
Но для нескольких строк кода
EJ.
Я делаю:
источник
Поскольку многие люди, вероятно, просматривают этот ответ при поиске log4j2 и почти все текущие ответы не учитывают log4j2 или недавние изменения в нем, следует надеяться, что это ответ на вопрос.
log4j2 поддерживает поставщиков (в настоящее время их собственная реализация, но согласно документации планируется использовать интерфейс поставщика Java в версии 3.0). Вы можете прочитать немного больше об этом в руководстве . Это позволяет вам поставить дорогое создание сообщения журнала в поставщика, который создает сообщение, только если оно будет зарегистрировано:
источник
Это повышает скорость, потому что обычно объединять строки в тексте отладки, что дорого, например:
источник
Начиная с версии Log4j
2.4
(илиslf4j-api 2.0.0-alpha1
), гораздо лучше использовать свободный API (или лямбда-поддержку Java 8 для отложенной регистрации ), поддерживающуюSupplier<?>
аргумент сообщения журнала, который может быть задан lambda :ИЛИ с API slf4j:
источник
Если вы используете вариант 2, вы делаете булеву проверку, которая выполняется быстро. В первом варианте вы выполняете вызов метода (помещая вещи в стек), а затем выполняете логическую проверку, которая все еще быстра. Проблема, которую я вижу, это последовательность. Если некоторые из ваших операторов отладки и информации обернуты, а некоторые нет, это не соответствует стилю кода. Плюс кто-то позже мог бы изменить оператор отладки, чтобы включить строки сцепления, что все еще довольно быстро. Я обнаружил, что когда мы завершили отладку и информацию в большом приложении и профилировали его, мы сэкономили пару процентов производительности. Не много, но достаточно, чтобы оно того стоило. Теперь у меня есть пара настроек макросов в IntelliJ для автоматического создания завернутых отладочных и информационных операторов для меня.
источник
Я бы порекомендовал использовать Вариант 2 как де-факто для большинства, так как это не супер дорого.
Случай 1: log.debug («одна строка»)
Case2: log.debug («одна строка» + «две строки» + object.toString + object2.toString)
В то время, когда любой из них вызывается, строка параметра в log.debug (будь то CASE 1 или Case2) должна быть оценена. Вот что все подразумевают под «дорогой». Если перед ним есть условие isDebugEnabled (), их не нужно оценивать, где сохраняется производительность.
источник
Начиная с версии 2.x, в Apache Log4j встроена эта проверка, поэтому в ней
isDebugEnabled()
больше нет необходимости. Просто сделайте,debug()
и сообщения будут подавлены, если не включены.источник
Log4j2 позволяет форматировать параметры в шаблон сообщения, аналогично
String.format()
, избавляя от необходимости делатьisDebugEnabled()
.Пример простого log4j2.properties:
источник