Производительность конкатенации строк в Log4j - PullRequest
0 голосов
/ 03 мая 2018

Я часто слышал, как люди говорят, что это один из лучших способов избегать String Concatenation и использовать вместо него {} во время регистрации.

Я искал код Log4j, чтобы увидеть, как они справились с этим, и подумал, что они делают нечто подобное.

Вот фрагмент метода format(), который принимает шаблон и аргументы и возвращает сообщение для регистрации.

/**
 * Formats arguments using SLF4J-like formatter.
 * @param pattern pattern, may be malformed.
 * @param arguments arguments.
 * @return Message string
 */
private static String format(final String pattern,
                             final Object[] arguments) {
    if (pattern != null) {
        String retval = "";
        int count = 0;
        int prev = 0;
        int pos = pattern.indexOf("{");
        while(pos >= 0) {
            if (pos == 0 || pattern.charAt(pos-1) != '\\') {
                retval += pattern.substring(prev, pos);
                if (pos + 1 < pattern.length() && pattern.charAt(pos+1) == '}') {
                    if(arguments != null && count < arguments.length) {
                        retval += arguments[count++];
                    } else {
                        retval += "{}";
                    }
                    prev = pos + 2;
                } else {
                    retval += "{";
                    prev = pos + 1;
                }
            } else {
                retval += pattern.substring(prev, pos - 1) + "{";
                prev = pos + 1;
            }
            pos = pattern.indexOf("{", prev);
        }
        return retval + pattern.substring(prev);
    }
    return null;
}

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

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Некоторые ответы на этот вопрос объясняют:

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

   Logger.debug("my name is {}", name);

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

В отличие от версии с конкатенацией строк

   Logger.debug("my name is " + name);

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


Но взгляните на этот пример:

   log.debug("Count: " + list.size());
   log.debug("Count: {}", list.size());

Версия формата будет быстрее, но обе версии всегда оценивают выражение list.size(). Если это дорогостоящая операция, возможно, вам придется прибегнуть к использованию охраны; например,

   if (log.isDebugEnabled()) {
       log.debug("Count: " + list.size());
   }
0 голосов
/ 03 мая 2018

Преимущество форматирования строк в системах журналирования состоит в том, что система журналирования может решить, должна ли происходить конкатенация строк.

Давайте использовать эти строки в качестве примера:

log.debug("Count: " + list.size());
log.debug("Count: {}", list.size());

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...