You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ck...@apache.org on 2021/08/24 20:23:35 UTC
[logging-log4j2] branch master updated: LOG4J2-1151: Prefer
`string.getBytes(Charset)` over `string.getBytes(String)`
This is an automated email from the ASF dual-hosted git repository.
ckozak pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/master by this push:
new 7bbd887 LOG4J2-1151: Prefer `string.getBytes(Charset)` over `string.getBytes(String)`
7bbd887 is described below
commit 7bbd8877e63149c5b1bae1f6e6c2a6562d10f4e2
Author: Carter Kozak <ck...@apache.org>
AuthorDate: Mon Aug 23 17:18:55 2021 -0400
LOG4J2-1151: Prefer `string.getBytes(Charset)` over `string.getBytes(String)`
Rerunning the benchmarks on modern java (in this case java 16,
however many optimizations are available in java 11 due to the
compact string optimizations) shows that the previous assumptions
no longer hold true:
```
Benchmark Mode Cnt Score Error Units
StringEncodingBenchmark.defaultStringGetBytes sample 299799 51.904 ± 1.399 ns/op
StringEncodingBenchmark.defaultStringGetBytes:defaultStringGetBytes·p0.00 sample 24.000 ns/op
StringEncodingBenchmark.defaultStringGetBytes:defaultStringGetBytes·p0.50 sample 46.000 ns/op
StringEncodingBenchmark.defaultStringGetBytes:defaultStringGetBytes·p0.90 sample 58.000 ns/op
StringEncodingBenchmark.defaultStringGetBytes:defaultStringGetBytes·p0.95 sample 61.000 ns/op
StringEncodingBenchmark.defaultStringGetBytes:defaultStringGetBytes·p0.99 sample 84.000 ns/op
StringEncodingBenchmark.defaultStringGetBytes:defaultStringGetBytes·p0.999 sample 406.200 ns/op
StringEncodingBenchmark.defaultStringGetBytes:defaultStringGetBytes·p0.9999 sample 15456.320 ns/op
StringEncodingBenchmark.defaultStringGetBytes:defaultStringGetBytes·p1.00 sample 27936.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesCharSet sample 308499 43.115 ± 1.269 ns/op
StringEncodingBenchmark.defaultStringGetBytesCharSet:defaultStringGetBytesCharSet·p0.00 sample 24.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesCharSet:defaultStringGetBytesCharSet·p0.50 sample 37.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesCharSet:defaultStringGetBytesCharSet·p0.90 sample 49.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesCharSet:defaultStringGetBytesCharSet·p0.95 sample 56.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesCharSet:defaultStringGetBytesCharSet·p0.99 sample 77.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesCharSet:defaultStringGetBytesCharSet·p0.999 sample 411.500 ns/op
StringEncodingBenchmark.defaultStringGetBytesCharSet:defaultStringGetBytesCharSet·p0.9999 sample 15381.600 ns/op
StringEncodingBenchmark.defaultStringGetBytesCharSet:defaultStringGetBytesCharSet·p1.00 sample 19296.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesString sample 193869 63.425 ± 2.415 ns/op
StringEncodingBenchmark.defaultStringGetBytesString:defaultStringGetBytesString·p0.00 sample 33.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesString:defaultStringGetBytesString·p0.50 sample 55.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesString:defaultStringGetBytesString·p0.90 sample 66.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesString:defaultStringGetBytesString·p0.95 sample 69.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesString:defaultStringGetBytesString·p0.99 sample 89.000 ns/op
StringEncodingBenchmark.defaultStringGetBytesString:defaultStringGetBytesString·p0.999 sample 845.700 ns/op
StringEncodingBenchmark.defaultStringGetBytesString:defaultStringGetBytesString·p0.9999 sample 15817.808 ns/op
StringEncodingBenchmark.defaultStringGetBytesString:defaultStringGetBytesString·p1.00 sample 16320.000 ns/op
StringEncodingBenchmark.iso8859_1CustomCastToByte sample 315863 55.002 ± 1.274 ns/op
StringEncodingBenchmark.iso8859_1CustomCastToByte:iso8859_1CustomCastToByte·p0.00 sample 35.000 ns/op
StringEncodingBenchmark.iso8859_1CustomCastToByte:iso8859_1CustomCastToByte·p0.50 sample 48.000 ns/op
StringEncodingBenchmark.iso8859_1CustomCastToByte:iso8859_1CustomCastToByte·p0.90 sample 62.000 ns/op
StringEncodingBenchmark.iso8859_1CustomCastToByte:iso8859_1CustomCastToByte·p0.95 sample 69.000 ns/op
StringEncodingBenchmark.iso8859_1CustomCastToByte:iso8859_1CustomCastToByte·p0.99 sample 78.000 ns/op
StringEncodingBenchmark.iso8859_1CustomCastToByte:iso8859_1CustomCastToByte·p0.999 sample 290.136 ns/op
StringEncodingBenchmark.iso8859_1CustomCastToByte:iso8859_1CustomCastToByte·p0.9999 sample 15629.235 ns/op
StringEncodingBenchmark.iso8859_1CustomCastToByte:iso8859_1CustomCastToByte·p1.00 sample 16272.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8 sample 203423 74.947 ± 2.029 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8:iso8859_1CustomPortedJDK8·p0.00 sample 51.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8:iso8859_1CustomPortedJDK8·p0.50 sample 66.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8:iso8859_1CustomPortedJDK8·p0.90 sample 80.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8:iso8859_1CustomPortedJDK8·p0.95 sample 82.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8:iso8859_1CustomPortedJDK8·p0.99 sample 90.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8:iso8859_1CustomPortedJDK8·p0.999 sample 425.880 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8:iso8859_1CustomPortedJDK8·p0.9999 sample 15680.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8:iso8859_1CustomPortedJDK8·p1.00 sample 25312.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8CopyArray sample 249565 98.996 ± 2.026 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8CopyArray:iso8859_1CustomPortedJDK8CopyArray·p0.00 sample 75.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8CopyArray:iso8859_1CustomPortedJDK8CopyArray·p0.50 sample 91.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8CopyArray:iso8859_1CustomPortedJDK8CopyArray·p0.90 sample 100.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8CopyArray:iso8859_1CustomPortedJDK8CopyArray·p0.95 sample 102.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8CopyArray:iso8859_1CustomPortedJDK8CopyArray·p0.99 sample 130.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8CopyArray:iso8859_1CustomPortedJDK8CopyArray·p0.999 sample 378.434 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8CopyArray:iso8859_1CustomPortedJDK8CopyArray·p0.9999 sample 15968.000 ns/op
StringEncodingBenchmark.iso8859_1CustomPortedJDK8CopyArray:iso8859_1CustomPortedJDK8CopyArray·p1.00 sample 17056.000 ns/op
StringEncodingBenchmark.iso8859_1CustomVerifyAndCast sample 210096 68.452 ± 1.793 ns/op
StringEncodingBenchmark.iso8859_1CustomVerifyAndCast:iso8859_1CustomVerifyAndCast·p0.00 sample 43.000 ns/op
StringEncodingBenchmark.iso8859_1CustomVerifyAndCast:iso8859_1CustomVerifyAndCast·p0.50 sample 66.000 ns/op
StringEncodingBenchmark.iso8859_1CustomVerifyAndCast:iso8859_1CustomVerifyAndCast·p0.90 sample 71.000 ns/op
StringEncodingBenchmark.iso8859_1CustomVerifyAndCast:iso8859_1CustomVerifyAndCast·p0.95 sample 72.000 ns/op
StringEncodingBenchmark.iso8859_1CustomVerifyAndCast:iso8859_1CustomVerifyAndCast·p0.99 sample 82.000 ns/op
StringEncodingBenchmark.iso8859_1CustomVerifyAndCast:iso8859_1CustomVerifyAndCast·p0.999 sample 281.903 ns/op
StringEncodingBenchmark.iso8859_1CustomVerifyAndCast:iso8859_1CustomVerifyAndCast·p0.9999 sample 15632.000 ns/op
StringEncodingBenchmark.iso8859_1CustomVerifyAndCast:iso8859_1CustomVerifyAndCast·p1.00 sample 16176.000 ns/op
StringEncodingBenchmark.iso8859_1Encoder sample 200539 404.110 ± 62.046 ns/op
StringEncodingBenchmark.iso8859_1Encoder:iso8859_1Encoder·p0.00 sample 334.000 ns/op
StringEncodingBenchmark.iso8859_1Encoder:iso8859_1Encoder·p0.50 sample 366.000 ns/op
StringEncodingBenchmark.iso8859_1Encoder:iso8859_1Encoder·p0.90 sample 387.000 ns/op
StringEncodingBenchmark.iso8859_1Encoder:iso8859_1Encoder·p0.95 sample 393.000 ns/op
StringEncodingBenchmark.iso8859_1Encoder:iso8859_1Encoder·p0.99 sample 449.000 ns/op
StringEncodingBenchmark.iso8859_1Encoder:iso8859_1Encoder·p0.999 sample 10432.000 ns/op
StringEncodingBenchmark.iso8859_1Encoder:iso8859_1Encoder·p0.9999 sample 16159.136 ns/op
StringEncodingBenchmark.iso8859_1Encoder:iso8859_1Encoder·p1.00 sample 3776512.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesCharSet sample 191618 37.300 ± 1.661 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesCharSet:iso8859_1StringGetBytesCharSet·p0.00 sample 21.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesCharSet:iso8859_1StringGetBytesCharSet·p0.50 sample 29.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesCharSet:iso8859_1StringGetBytesCharSet·p0.90 sample 42.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesCharSet:iso8859_1StringGetBytesCharSet·p0.95 sample 46.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesCharSet:iso8859_1StringGetBytesCharSet·p0.99 sample 56.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesCharSet:iso8859_1StringGetBytesCharSet·p0.999 sample 432.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesCharSet:iso8859_1StringGetBytesCharSet·p0.9999 sample 15443.048 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesCharSet:iso8859_1StringGetBytesCharSet·p1.00 sample 16160.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesString sample 324805 44.331 ± 1.504 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesString:iso8859_1StringGetBytesString·p0.00 sample 25.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesString:iso8859_1StringGetBytesString·p0.50 sample 39.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesString:iso8859_1StringGetBytesString·p0.90 sample 48.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesString:iso8859_1StringGetBytesString·p0.95 sample 52.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesString:iso8859_1StringGetBytesString·p0.99 sample 84.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesString:iso8859_1StringGetBytesString·p0.999 sample 391.000 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesString:iso8859_1StringGetBytesString·p0.9999 sample 15609.552 ns/op
StringEncodingBenchmark.iso8859_1StringGetBytesString:iso8859_1StringGetBytesString·p1.00 sample 58368.000 ns/op
StringEncodingBenchmark.shiftJisEncoder sample 295798 519.145 ± 40.724 ns/op
StringEncodingBenchmark.shiftJisEncoder:shiftJisEncoder·p0.00 sample 455.000 ns/op
StringEncodingBenchmark.shiftJisEncoder:shiftJisEncoder·p0.50 sample 487.000 ns/op
StringEncodingBenchmark.shiftJisEncoder:shiftJisEncoder·p0.90 sample 513.000 ns/op
StringEncodingBenchmark.shiftJisEncoder:shiftJisEncoder·p0.95 sample 521.000 ns/op
StringEncodingBenchmark.shiftJisEncoder:shiftJisEncoder·p0.99 sample 590.000 ns/op
StringEncodingBenchmark.shiftJisEncoder:shiftJisEncoder·p0.999 sample 5011.256 ns/op
StringEncodingBenchmark.shiftJisEncoder:shiftJisEncoder·p0.9999 sample 16342.722 ns/op
StringEncodingBenchmark.shiftJisEncoder:shiftJisEncoder·p1.00 sample 3653632.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesCharSet sample 291714 86.313 ± 1.686 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesCharSet:shiftJisStringGetBytesCharSet·p0.00 sample 60.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesCharSet:shiftJisStringGetBytesCharSet·p0.50 sample 74.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesCharSet:shiftJisStringGetBytesCharSet·p0.90 sample 84.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesCharSet:shiftJisStringGetBytesCharSet·p0.95 sample 93.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesCharSet:shiftJisStringGetBytesCharSet·p0.99 sample 368.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesCharSet:shiftJisStringGetBytesCharSet·p0.999 sample 978.570 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesCharSet:shiftJisStringGetBytesCharSet·p0.9999 sample 15904.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesCharSet:shiftJisStringGetBytesCharSet·p1.00 sample 16800.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesString sample 296544 45.989 ± 1.286 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesString:shiftJisStringGetBytesString·p0.00 sample 28.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesString:shiftJisStringGetBytesString·p0.50 sample 42.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesString:shiftJisStringGetBytesString·p0.90 sample 48.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesString:shiftJisStringGetBytesString·p0.95 sample 50.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesString:shiftJisStringGetBytesString·p0.99 sample 60.000 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesString:shiftJisStringGetBytesString·p0.999 sample 378.455 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesString:shiftJisStringGetBytesString·p0.9999 sample 15573.528 ns/op
StringEncodingBenchmark.shiftJisStringGetBytesString:shiftJisStringGetBytesString·p1.00 sample 16416.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesCharSet sample 211373 70.209 ± 2.050 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesCharSet:usAsciiStringGetBytesCharSet·p0.00 sample 48.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesCharSet:usAsciiStringGetBytesCharSet·p0.50 sample 61.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesCharSet:usAsciiStringGetBytesCharSet·p0.90 sample 74.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesCharSet:usAsciiStringGetBytesCharSet·p0.95 sample 75.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesCharSet:usAsciiStringGetBytesCharSet·p0.99 sample 86.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesCharSet:usAsciiStringGetBytesCharSet·p0.999 sample 271.626 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesCharSet:usAsciiStringGetBytesCharSet·p0.9999 sample 15840.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesCharSet:usAsciiStringGetBytesCharSet·p1.00 sample 19584.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesString sample 345053 79.109 ± 14.984 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesString:usAsciiStringGetBytesString·p0.00 sample 60.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesString:usAsciiStringGetBytesString·p0.50 sample 68.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesString:usAsciiStringGetBytesString·p0.90 sample 83.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesString:usAsciiStringGetBytesString·p0.95 sample 87.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesString:usAsciiStringGetBytesString·p0.99 sample 91.000 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesString:usAsciiStringGetBytesString·p0.999 sample 156.946 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesString:usAsciiStringGetBytesString·p0.9999 sample 15527.395 ns/op
StringEncodingBenchmark.usAsciiStringGetBytesString:usAsciiStringGetBytesString·p1.00 sample 1566720.000 ns/op
```
---
.../log4j/core/layout/AbstractStringLayout.java | 32 ++--------------------
.../logging/log4j/core/util/StringEncoder.java | 28 +++++++++++--------
src/changes/changes.xml | 4 +++
3 files changed, 22 insertions(+), 42 deletions(-)
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
index 0bb2b94..76dd5d4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
@@ -16,7 +16,6 @@
*/
package org.apache.logging.log4j.core.layout;
-import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@@ -41,10 +40,6 @@ import org.apache.logging.log4j.util.Strings;
* performance: all characters are simply cast to bytes.
* </p>
*/
-/*
- * Implementation note: prefer String.getBytes(String) to String.getBytes(Charset) for performance reasons. See
- * https://issues.apache.org/jira/browse/LOG4J2-935 for details.
- */
public abstract class AbstractStringLayout extends AbstractLayout<String> implements StringLayout {
public abstract static class Builder<B extends Builder<B>> extends AbstractLayout.Builder<B> {
@@ -139,11 +134,6 @@ public abstract class AbstractStringLayout extends AbstractLayout<String> implem
return result;
}
- // LOG4J2-1151: If the built-in JDK 8 encoders are available we should use them.
- private static boolean isPreJava8() {
- return org.apache.logging.log4j.util.Constants.JAVA_MAJOR_VERSION < 8;
- }
-
private static int size(final String property, final int defaultValue) {
return PropertiesUtil.getProperties().getIntegerProperty(property, defaultValue);
}
@@ -156,17 +146,12 @@ public abstract class AbstractStringLayout extends AbstractLayout<String> implem
/**
* The charset for the formatted message.
*/
- // LOG4J2-1099: Charset cannot be final due to serialization needs, so we serialize as Charset name instead
- private transient Charset charset;
-
- private final String charsetName;
+ private final Charset charset;
private final Serializer footerSerializer;
private final Serializer headerSerializer;
- private final boolean useCustomEncoding;
-
protected AbstractStringLayout(final Charset charset) {
this(charset, (byte[]) null, (byte[]) null);
}
@@ -183,9 +168,6 @@ public abstract class AbstractStringLayout extends AbstractLayout<String> implem
this.headerSerializer = null;
this.footerSerializer = null;
this.charset = aCharset == null ? StandardCharsets.UTF_8 : aCharset;
- this.charsetName = this.charset.name();
- useCustomEncoding = isPreJava8()
- && (StandardCharsets.ISO_8859_1.equals(aCharset) || StandardCharsets.US_ASCII.equals(aCharset));
textEncoder = Constants.ENABLE_DIRECT_ENCODERS ? new StringBuilderEncoder(charset) : null;
}
@@ -203,21 +185,11 @@ public abstract class AbstractStringLayout extends AbstractLayout<String> implem
this.headerSerializer = headerSerializer;
this.footerSerializer = footerSerializer;
this.charset = aCharset == null ? StandardCharsets.UTF_8 : aCharset;
- this.charsetName = this.charset.name();
- useCustomEncoding = isPreJava8()
- && (StandardCharsets.ISO_8859_1.equals(aCharset) || StandardCharsets.US_ASCII.equals(aCharset));
textEncoder = Constants.ENABLE_DIRECT_ENCODERS ? new StringBuilderEncoder(charset) : null;
}
protected byte[] getBytes(final String s) {
- if (useCustomEncoding) { // rely on branch prediction to eliminate this check if false
- return StringEncoder.encodeSingleByteChars(s);
- }
- try { // LOG4J2-935: String.getBytes(String) gives better performance
- return s.getBytes(charsetName);
- } catch (final UnsupportedEncodingException e) {
- return s.getBytes(charset);
- }
+ return s.getBytes(charset);
}
@Override
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/StringEncoder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/StringEncoder.java
index bd82c28..610515a 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/StringEncoder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/StringEncoder.java
@@ -16,9 +16,7 @@
*/
package org.apache.logging.log4j.core.util;
-import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
/**
* Encodes Strings to bytes.
@@ -39,26 +37,21 @@ public final class StringEncoder {
*/
public static byte[] toBytes(final String str, final Charset charset) {
if (str != null) {
- if (StandardCharsets.ISO_8859_1.equals(charset)) {
- return encodeSingleByteChars(str);
- }
- final Charset actual = charset != null ? charset : Charset.defaultCharset();
- try { // LOG4J2-935: String.getBytes(String) gives better performance
- return str.getBytes(actual.name());
- } catch (final UnsupportedEncodingException e) {
- return str.getBytes(actual);
- }
+ return str.getBytes(charset != null ? charset : Charset.defaultCharset());
}
return null;
}
/**
+ * Prefer standard {@link String#getBytes(Charset)} which performs better in Java 8 and beyond.
* Encodes the specified char sequence by casting each character to a byte.
*
* @param s the char sequence to encode
* @return the encoded String
* @see <a href="https://issues.apache.org/jira/browse/LOG4J2-1151">LOG4J2-1151</a>
+ * @deprecated No longer necessary given better performance in Java 8
*/
+ @Deprecated
public static byte[] encodeSingleByteChars(final CharSequence s) {
final int length = s.length();
final byte[] result = new byte[length];
@@ -67,10 +60,15 @@ public final class StringEncoder {
}
// LOG4J2-1151
- /*
+ /**
+ * Prefer standard {@link String#getBytes(Charset)} which performs better in Java 8 and beyond.
+ *
* Implementation note: this is the fast path. If the char array contains only ISO-8859-1 characters, all the work
* will be done here.
+ *
+ * @deprecated No longer necessary given better performance in Java 8
*/
+ @Deprecated
public static int encodeIsoChars(final CharSequence charArray, int charIndex, final byte[] byteArray, int byteIndex, final int length) {
int i = 0;
for (; i < length; i++) {
@@ -84,6 +82,12 @@ public final class StringEncoder {
}
// LOG4J2-1151
+
+ /**
+ * Prefer standard {@link String#getBytes(Charset)} which performs better in Java 8 and beyond.
+ * @deprecated No longer necessary given better performance in Java 8
+ */
+ @Deprecated
public static int encodeString(final CharSequence charArray, int charOffset, int charLength, final byte[] byteArray) {
int byteOffset = 0;
int length = Math.min(charLength, byteArray.length);
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 3521955..875345a 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -229,6 +229,10 @@
and MemoryMappedFileManager due to the unused setEndOfBatch and isEndOfBatch methods.
The methods on LogEvent are preferred.
</action>
+ <action issue="LOG4J2-1151" dev="ckozak" type="add">
+ Prefer string.getBytes(Charset) over string.getBytes(String)
+ based on performance improvements in modern Java releases.
+ </action>
<!-- FIXES -->
<action issue="LOG4J2-3142" dev="ckozak" type="fix" due-to="John Meikle">
log4j-1.2-api implements LogEventAdapter.getTimestamp() based on the original event timestamp