LOG4J2-1321 Avoid allocating unnecessary temporary objects in PatternLayout's NamePatternConverter and ClassNamePatternConverter
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/e39a2da5 Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/e39a2da5 Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/e39a2da5 Branch: refs/heads/gelf-layout-gc-free Commit: e39a2da57c33b49b786756b0b588152d19afd47f Parents: 6ba91a3 Author: rpopma <[email protected]> Authored: Fri Mar 18 07:42:01 2016 +0900 Committer: rpopma <[email protected]> Committed: Fri Mar 18 07:42:01 2016 +0900 ---------------------------------------------------------------------- .../core/pattern/ClassNamePatternConverter.java | 2 +- .../core/pattern/LoggerPatternConverter.java | 2 +- .../log4j/core/pattern/NameAbbreviator.java | 53 +++++++++++--------- .../core/pattern/NamePatternConverter.java | 7 +-- .../log4j/core/pattern/NameAbbreviatorTest.java | 14 +++++- src/changes/changes.xml | 3 ++ 6 files changed, 52 insertions(+), 29 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e39a2da5/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ClassNamePatternConverter.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ClassNamePatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ClassNamePatternConverter.java index a2e0f2a..30f580f 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ClassNamePatternConverter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ClassNamePatternConverter.java @@ -61,7 +61,7 @@ public final class ClassNamePatternConverter extends NamePatternConverter { if (element == null) { toAppendTo.append(NA); } else { - toAppendTo.append(abbreviate(element.getClassName())); + abbreviate(element.getClassName(), toAppendTo); } } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e39a2da5/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/LoggerPatternConverter.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/LoggerPatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/LoggerPatternConverter.java index 2b5651b..d6b43c0 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/LoggerPatternConverter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/LoggerPatternConverter.java @@ -61,6 +61,6 @@ public final class LoggerPatternConverter extends NamePatternConverter { */ @Override public void format(final LogEvent event, final StringBuilder toAppendTo) { - toAppendTo.append(abbreviate(event.getLoggerName())); + abbreviate(event.getLoggerName(), toAppendTo); } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e39a2da5/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/NameAbbreviator.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/NameAbbreviator.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/NameAbbreviator.java index e145f81..1271ad5 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/NameAbbreviator.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/NameAbbreviator.java @@ -127,10 +127,11 @@ public abstract class NameAbbreviator { /** * Abbreviates a name in a String. * - * @param buf buffer, may not be null. + * @param original the text to abbreviate, may not be null. + * @param destination StringBuilder to write the result to * @return The abbreviated String. */ - public abstract String abbreviate(final String buf); + public abstract void abbreviate(final String original, final StringBuilder destination); /** * Abbreviator that simply appends full name to buffer. @@ -146,8 +147,8 @@ public abstract class NameAbbreviator { * {@inheritDoc} */ @Override - public String abbreviate(final String buf) { - return buf; + public void abbreviate(final String original, final StringBuilder destination) { + destination.append(original); } } @@ -172,25 +173,26 @@ public abstract class NameAbbreviator { /** * Abbreviate name. * - * @param buf The String to abbreviate. + * @param original The String to abbreviate. + * @param destination * @return the abbreviated String. */ @Override - public String abbreviate(final String buf) { + public void abbreviate(final String original, final StringBuilder destination) { // We subtract 1 from 'len' when assigning to 'end' to avoid out of // bounds exception in return r.substring(end+1, len). This can happen if // precision is 1 and the category name ends with a dot. - int end = buf.length() - 1; + int end = original.length() - 1; for (int i = count; i > 0; i--) { - end = buf.lastIndexOf('.', end - 1); + end = original.lastIndexOf('.', end - 1); if (end == -1) { - return buf; + destination.append(original); + return; } } - - return buf.substring(end + 1); + destination.append(original, end + 1, original.length()); } } @@ -230,8 +232,15 @@ public abstract class NameAbbreviator { * @return starting index of next element. */ public int abbreviate(final StringBuilder buf, final int startPos) { - int nextDot = buf.toString().indexOf('.', startPos); - + final int start = (startPos < 0) ? 0 : startPos; + final int max = buf.length(); + int nextDot = -1; + for (int i = start; i < max; i++) { + if (buf.charAt(i) == '.') { + nextDot = i; + break; + } + } if (nextDot != -1) { if (nextDot - startPos > charCount) { buf.delete(startPos + charCount, nextDot); @@ -242,10 +251,8 @@ public abstract class NameAbbreviator { nextDot++; } } - nextDot++; } - return nextDot; } } @@ -277,18 +284,19 @@ public abstract class NameAbbreviator { /** * Abbreviates name. * - * @param buf buffer that abbreviated name is appended. + * @param original buffer that abbreviated name is appended. + * @param destination */ @Override - public String abbreviate(final String buf) { + public void abbreviate(final String original, final StringBuilder destination) { // // all non-terminal patterns are executed once // - int pos = 0; - final StringBuilder sb = new StringBuilder(buf); + int pos = destination.length(); + final int max = pos + original.length(); + final StringBuilder sb = destination.append(original);//new StringBuilder(original); - for (int i = 0; i < fragments.length - 1 && pos < buf.length(); - i++) { + for (int i = 0; i < fragments.length - 1 && pos < original.length(); i++) { pos = fragments[i].abbreviate(sb, pos); } @@ -297,10 +305,9 @@ public abstract class NameAbbreviator { // final PatternAbbreviatorFragment terminalFragment = fragments[fragments.length - 1]; - while (pos < buf.length() && pos >= 0) { + while (pos < max && pos >= 0) { pos = terminalFragment.abbreviate(sb, pos); } - return sb.toString(); } } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e39a2da5/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/NamePatternConverter.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/NamePatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/NamePatternConverter.java index b35c787..a33a9cc 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/NamePatternConverter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/NamePatternConverter.java @@ -46,10 +46,11 @@ public abstract class NamePatternConverter extends LogEventPatternConverter { /** * Abbreviate name in string buffer. * - * @param buf string buffer containing name. + * @param original string containing name. + * @param destination the StringBuilder to write to * @return The abbreviated name. */ - protected final String abbreviate(final String buf) { - return abbreviator.abbreviate(buf); + protected final void abbreviate(final String original, final StringBuilder destination) { + abbreviator.abbreviate(original, destination); } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e39a2da5/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NameAbbreviatorTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NameAbbreviatorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NameAbbreviatorTest.java index 441d7db..4b03076 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NameAbbreviatorTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NameAbbreviatorTest.java @@ -58,8 +58,20 @@ public class NameAbbreviatorTest { @Test public void testAbbreviatorPatterns() throws Exception { final NameAbbreviator abbreviator = NameAbbreviator.getAbbreviator(this.pattern); - final String actual = abbreviator.abbreviate(this.getClass().getName()); + final StringBuilder destination = new StringBuilder(); + abbreviator.abbreviate(this.getClass().getName(), destination); + final String actual = destination.toString(); assertEquals(expected, actual); } + @Test + public void testAbbreviatorPatternsAppend() throws Exception { + final NameAbbreviator abbreviator = NameAbbreviator.getAbbreviator(this.pattern); + final String PREFIX = "some random text"; + final StringBuilder destination = new StringBuilder(PREFIX); + abbreviator.abbreviate(this.getClass().getName(), destination); + final String actual = destination.toString(); + assertEquals(PREFIX + expected, actual); + } + } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e39a2da5/src/changes/changes.xml ---------------------------------------------------------------------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 3d56a5a..5357d96 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -24,6 +24,9 @@ </properties> <body> <release version="2.6" date="2016-MM-DD" description="GA Release 2.6"> + <action issue="LOG4J2-1321" dev="rpopma" type="update"> + Avoid allocating unnecessary temporary objects in PatternLayout's NamePatternConverter and ClassNamePatternConverter. + </action> <action issue="LOG4J2-1309" dev="ggregory" type="fix"> Configuration file error does not show cause exception. </action>
