You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2015/08/22 14:00:13 UTC
logging-log4j2 git commit: LOG4J2-1097 renamed CustomTimeFormat to
FixedTimeFormat, fixed bug, added unit tests,
renamed fields & methods in benchmarks
Repository: logging-log4j2
Updated Branches:
refs/heads/master 76212686b -> d8935c8a8
LOG4J2-1097 renamed CustomTimeFormat to FixedTimeFormat, fixed bug,
added unit tests, renamed fields & methods in benchmarks
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/d8935c8a
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/d8935c8a
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/d8935c8a
Branch: refs/heads/master
Commit: d8935c8a8015caa396be554afbbd4f0190c42d8b
Parents: 7621268
Author: rpopma <rp...@apache.org>
Authored: Sat Aug 22 21:00:23 2015 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sat Aug 22 21:00:23 2015 +0900
----------------------------------------------------------------------
.../core/util/datetime/CustomTimeFormat.java | 292 ------------------
.../core/util/datetime/FixedDateFormat.java | 299 +++++++++++++++++++
.../util/datetime/CustomTimeFormatTest.java | 154 ----------
.../core/util/datetime/FixedDateFormatTest.java | 203 +++++++++++++
.../perf/jmh/ThreadsafeDateFormatBenchmark.java | 86 +++---
.../log4j/perf/jmh/TimeFormatBenchmark.java | 20 +-
6 files changed, 555 insertions(+), 499 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d8935c8a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/CustomTimeFormat.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/CustomTimeFormat.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/CustomTimeFormat.java
deleted file mode 100644
index da90b44..0000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/CustomTimeFormat.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-
-package org.apache.logging.log4j.core.util.datetime;
-
-import java.util.Calendar;
-import java.util.Objects;
-
-/**
- * Custom time formatter that trades flexibility for performance.
- */
-public class CustomTimeFormat {
- /**
- * Enumeration over the supported date/time format patterns.
- * <p>
- * Package protected for unit tests.
- */
- static enum FixedFormat {
- /**
- * ABSOLUTE time format: {@code "HH:mm:ss,SSS"}.
- */
- ABSOLUTE("HH:mm:ss,SSS", null, 0, ':', 1, ',', 1),
-
- /**
- * ABSOLUTE time format variation with period separator: {@code "HH:mm:ss.SSS"}.
- */
- ABSOLUTE2("HH:mm:ss.SSS", null, 0, ':', 1, '.', 1),
-
- /**
- * COMPACT time format: {@code "yyyyMMddHHmmssSSS"}.
- */
- COMPACT("yyyyMMddHHmmssSSS", "yyyyMMdd", 0, ' ', 0, ' ', 0),
-
- /**
- * DATE time format: {@code "dd MMM yyyy HH:mm:ss,SSS"}.
- */
- DATE("dd MMM yyyy HH:mm:ss,SSS", "dd MMM yyyy ", 0, ':', 1, ',', 1),
-
- /**
- * DATE time format variation with period separator: {@code "dd MMM yyyy HH:mm:ss.SSS"}.
- */
- DATE2("dd MMM yyyy HH:mm:ss.SSS", "dd MMM yyyy ", 0, ':', 1, '.', 1),
-
- /**
- * DEFAULT time format: {@code "yyyy-MM-dd HH:mm:ss,SSS"}.
- */
- DEFAULT("yyyy-MM-dd HH:mm:ss,SSS", "yyyy-MM-dd ", 0, ':', 1, ',', 1),
-
- /**
- * DEFAULT time format variation with period separator: {@code "yyyy-MM-dd HH:mm:ss.SSS"}.
- */
- DEFAULT2("yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd ", 0, ':', 1, '.', 1),
-
- /**
- * ISO8601_BASIC time format: {@code "yyyyMMdd'T'HHmmss,SSS"}.
- */
- ISO8601_BASIC("yyyyMMdd'T'HHmmss,SSS", "yyyyMMdd'T'", 2, ' ', 0, ',', 1),
-
- /**
- * ISO8601 time format: {@code "yyyy-MM-dd'T'HH:mm:ss,SSS"}.
- */
- ISO8601("yyyy-MM-dd'T'HH:mm:ss,SSS", "yyyy-MM-dd'T'", 2, ':', 1, ',', 1), ;
-
- private final String pattern;
- private final String datePattern;
- private final int escapeCount;
- private final char timeSeparatorChar;
- private final int timeSeparatorLength;
- private final char millisSeparatorChar;
- private final int millisSeparatorLength;
-
- private FixedFormat(final String pattern, final String datePattern, final int escapeCount,
- final char timeSeparator, final int timeSepLength, final char millisSeparator, final int millisSepLength) {
- this.timeSeparatorChar = timeSeparator;
- this.timeSeparatorLength = timeSepLength;
- this.millisSeparatorChar = millisSeparator;
- this.millisSeparatorLength = millisSepLength;
- this.pattern = Objects.requireNonNull(pattern);
- this.datePattern = datePattern; // may be null
- this.escapeCount = escapeCount;
- }
-
- public String getPattern() {
- return pattern;
- }
-
- public String getDatePattern() {
- return datePattern;
- }
-
- /**
- * Returns the FixedFormat with the name or pattern matching the specified string or {@code null} if not found.
- */
- public static FixedFormat lookup(final String nameOrPattern) {
- for (final FixedFormat type : FixedFormat.values()) {
- if (type.name().equals(nameOrPattern) || type.getPattern().equals(nameOrPattern)) {
- return type;
- }
- }
- return null;
- }
-
- public int getLength() {
- return pattern.length() - escapeCount;
- }
-
- public int getDatePatternLength() {
- return getDatePattern() == null ? 0 : getDatePattern().length() - escapeCount;
- }
-
- public FastDateFormat getFastDateFormat() {
- return getDatePattern() == null ? null : FastDateFormat.getInstance(getDatePattern());
- }
- }
-
- public static CustomTimeFormat createIfSupported(final String... options) {
- if (options == null || options.length == 0 || options.length > 1) {
- return null; // time zone not supported
- }
- final FixedFormat type = FixedFormat.lookup(options[0]);
- return type == null ? null : new CustomTimeFormat(type);
- }
-
- private final FixedFormat type;
- private final int length;
- private final int dateLength;
- private final FastDateFormat fastDateFormat; // may be null
- private final char timeSeparatorChar;
- private final char millisSeparatorChar;
- private final int timeSeparatorLength;
- private final int millisSeparatorLength;
-
- private volatile long midnightToday = 0;
- private volatile long midnightTomorrow = 0;
- // cachedDate does not need to be volatile because
- // there is a write to a volatile field *after* cachedDate is modified,
- // and there is a read from a volatile field *before* cachedDate is read.
- // The Java memory model guarantees that because of the above,
- // changes to cachedDate in one thread are visible to other threads.
- // See http://g.oswego.edu/dl/jmm/cookbook.html
- private char[] cachedDate; // may be null
-
- /**
- * Constructs a CustomTimeFormat for the specified fixed format.
- * <p>
- * Package protected for unit tests.
- *
- * @param type the fixed format
- */
- CustomTimeFormat(final FixedFormat type) {
- this.type = Objects.requireNonNull(type);
- this.timeSeparatorChar = type.timeSeparatorChar;
- this.timeSeparatorLength = type.timeSeparatorLength;
- this.millisSeparatorChar = type.millisSeparatorChar;
- this.millisSeparatorLength = type.millisSeparatorLength;
- this.length = type.getLength();
- this.dateLength = type.getDatePatternLength();
- this.fastDateFormat = type.getFastDateFormat();
- }
-
- public String getFormat() {
- return type.getPattern();
- }
-
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 21 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes)
- private long millisSinceMidnight(final long now) {
- if (now >= midnightTomorrow) {
- updateMidnightMillis(now);
- }
- return now - midnightToday;
- }
-
- private void updateMidnightMillis(final long now) {
-
- updateCachedDate(now);
-
- midnightToday = calcMidnightMillis(now, 0);
- midnightTomorrow = calcMidnightMillis(now, 1);
- }
-
- static long calcMidnightMillis(final long time, final int addDays) {
- final Calendar cal = Calendar.getInstance();
- cal.setTimeInMillis(time);
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.DATE, addDays);
- return cal.getTimeInMillis();
- }
-
- private void updateCachedDate(final long now) {
- if (fastDateFormat != null) {
- final StringBuilder result = fastDateFormat.format(now, new StringBuilder());
- cachedDate = result.toString().toCharArray();
- }
- }
-
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 28 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes)
- public String format(final long time) {
- final char[] result = new char[length];
- int written = format(time, result, 0);
- return new String(result, 0, written);
- }
-
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 31 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes)
- public int format(final long time, final char[] buffer, final int startPos) {
- // Calculate values by getting the ms values first and do then
- // calculate the hour minute and second values divisions.
-
- // Get daytime in ms: this does fit into an int
- // int ms = (int) (time % 86400000);
- final int ms = (int) (millisSinceMidnight(time));
- writeDate(buffer, startPos);
- return writeTime(ms, buffer, startPos + dateLength) - startPos;
- }
-
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 22 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes)
- private void writeDate(final char[] buffer, final int startPos) {
- if (cachedDate != null) {
- System.arraycopy(cachedDate, 0, buffer, startPos, dateLength);
- }
- }
-
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 262 bytes (will be inlined when hot enough: <= -XX:FreqInlineSize=325 bytes on Linux)
- private int writeTime(int ms, final char[] buffer, int pos) {
- final int hours = ms / 3600000;
- ms -= 3600000 * hours;
-
- final int minutes = ms / 60000;
- ms -= 60000 * minutes;
-
- final int seconds = ms / 1000;
- ms -= 1000 * seconds;
-
- // Hour
- int temp = hours / 10;
- buffer[pos++] = ((char) (temp + '0'));
-
- // Do subtract to get remainder instead of doing % 10
- buffer[pos++] = ((char) (hours - 10 * temp + '0'));
- buffer[pos] = timeSeparatorChar;
- pos += timeSeparatorLength;
-
- // Minute
- temp = minutes / 10;
- buffer[pos++] = ((char) (temp + '0'));
-
- // Do subtract to get remainder instead of doing % 10
- buffer[pos++] = ((char) (minutes - 10 * temp + '0'));
- buffer[pos] = timeSeparatorChar;
- pos += timeSeparatorLength;
-
- // Second
- temp = seconds / 10;
- buffer[pos++] = ((char) (temp + '0'));
- buffer[pos++] = ((char) (seconds - 10 * temp + '0'));
- buffer[pos] = millisSeparatorChar;
- pos += millisSeparatorLength;
-
- // Millisecond
- temp = ms / 100;
- buffer[pos++] = ((char) (temp + '0'));
-
- ms -= 100 * temp;
- temp = ms / 10;
- buffer[pos++] = ((char) (temp + '0'));
-
- ms -= 10 * temp;
- buffer[pos++] = ((char) (ms + '0'));
- return pos;
- }
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d8935c8a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FixedDateFormat.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FixedDateFormat.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FixedDateFormat.java
new file mode 100644
index 0000000..b65fb2b
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FixedDateFormat.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.util.datetime;
+
+import java.util.Calendar;
+import java.util.Objects;
+
+/**
+ * Custom time formatter that trades flexibility for performance.
+ */
+public class FixedDateFormat {
+ /**
+ * Enumeration over the supported date/time format patterns.
+ * <p>
+ * Package protected for unit tests.
+ */
+ public static enum FixedFormat {
+ /**
+ * ABSOLUTE time format: {@code "HH:mm:ss,SSS"}.
+ */
+ ABSOLUTE("HH:mm:ss,SSS", null, 0, ':', 1, ',', 1),
+
+ /**
+ * ABSOLUTE time format variation with period separator: {@code "HH:mm:ss.SSS"}.
+ */
+ ABSOLUTE_PERIOD("HH:mm:ss.SSS", null, 0, ':', 1, '.', 1),
+
+ /**
+ * COMPACT time format: {@code "yyyyMMddHHmmssSSS"}.
+ */
+ COMPACT("yyyyMMddHHmmssSSS", "yyyyMMdd", 0, ' ', 0, ' ', 0),
+
+ /**
+ * DATE_AND_TIME time format: {@code "dd MMM yyyy HH:mm:ss,SSS"}.
+ */
+ DATE("dd MMM yyyy HH:mm:ss,SSS", "dd MMM yyyy ", 0, ':', 1, ',', 1),
+
+ /**
+ * DATE_AND_TIME time format variation with period separator: {@code "dd MMM yyyy HH:mm:ss.SSS"}.
+ */
+ DATE_PERIOD("dd MMM yyyy HH:mm:ss.SSS", "dd MMM yyyy ", 0, ':', 1, '.', 1),
+
+ /**
+ * DEFAULT time format: {@code "yyyy-MM-dd HH:mm:ss,SSS"}.
+ */
+ DEFAULT("yyyy-MM-dd HH:mm:ss,SSS", "yyyy-MM-dd ", 0, ':', 1, ',', 1),
+
+ /**
+ * DEFAULT time format variation with period separator: {@code "yyyy-MM-dd HH:mm:ss.SSS"}.
+ */
+ DEFAULT_PERIOD("yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd ", 0, ':', 1, '.', 1),
+
+ /**
+ * ISO8601_BASIC time format: {@code "yyyyMMdd'T'HHmmss,SSS"}.
+ */
+ ISO8601_BASIC("yyyyMMdd'T'HHmmss,SSS", "yyyyMMdd'T'", 2, ' ', 0, ',', 1),
+
+ /**
+ * ISO8601 time format: {@code "yyyy-MM-dd'T'HH:mm:ss,SSS"}.
+ */
+ ISO8601("yyyy-MM-dd'T'HH:mm:ss,SSS", "yyyy-MM-dd'T'", 2, ':', 1, ',', 1), ;
+
+ private final String pattern;
+ private final String datePattern;
+ private final int escapeCount;
+ private final char timeSeparatorChar;
+ private final int timeSeparatorLength;
+ private final char millisSeparatorChar;
+ private final int millisSeparatorLength;
+
+ private FixedFormat(final String pattern, final String datePattern, final int escapeCount,
+ final char timeSeparator, final int timeSepLength, final char millisSeparator, final int millisSepLength) {
+ this.timeSeparatorChar = timeSeparator;
+ this.timeSeparatorLength = timeSepLength;
+ this.millisSeparatorChar = millisSeparator;
+ this.millisSeparatorLength = millisSepLength;
+ this.pattern = Objects.requireNonNull(pattern);
+ this.datePattern = datePattern; // may be null
+ this.escapeCount = escapeCount;
+ }
+
+ public String getPattern() {
+ return pattern;
+ }
+
+ public String getDatePattern() {
+ return datePattern;
+ }
+
+ /**
+ * Returns the FixedFormat with the name or pattern matching the specified string or {@code null} if not found.
+ */
+ public static FixedFormat lookup(final String nameOrPattern) {
+ for (final FixedFormat type : FixedFormat.values()) {
+ if (type.name().equals(nameOrPattern) || type.getPattern().equals(nameOrPattern)) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+ public int getLength() {
+ return pattern.length() - escapeCount;
+ }
+
+ public int getDatePatternLength() {
+ return getDatePattern() == null ? 0 : getDatePattern().length() - escapeCount;
+ }
+
+ public FastDateFormat getFastDateFormat() {
+ return getDatePattern() == null ? null : FastDateFormat.getInstance(getDatePattern());
+ }
+ }
+
+ public static FixedDateFormat createIfSupported(final String... options) {
+ if (options == null || options.length == 0 || options[0] == null) {
+ return new FixedDateFormat(FixedFormat.DEFAULT);
+ }
+ if (options.length > 1) {
+ return null; // time zone not supported
+ }
+ final FixedFormat type = FixedFormat.lookup(options[0]);
+ return type == null ? null : new FixedDateFormat(type);
+ }
+
+ public static FixedDateFormat create(FixedFormat format) {
+ return new FixedDateFormat(format);
+ }
+
+ private final FixedFormat fixedFormat;
+ private final int length;
+ private final int dateLength;
+ private final FastDateFormat fastDateFormat; // may be null
+ private final char timeSeparatorChar;
+ private final char millisSeparatorChar;
+ private final int timeSeparatorLength;
+ private final int millisSeparatorLength;
+
+ private volatile long midnightToday = 0;
+ private volatile long midnightTomorrow = 0;
+ // cachedDate does not need to be volatile because
+ // there is a write to a volatile field *after* cachedDate is modified,
+ // and there is a read from a volatile field *before* cachedDate is read.
+ // The Java memory model guarantees that because of the above,
+ // changes to cachedDate in one thread are visible to other threads.
+ // See http://g.oswego.edu/dl/jmm/cookbook.html
+ private char[] cachedDate; // may be null
+
+ /**
+ * Constructs a FixedDateFormat for the specified fixed format.
+ * <p>
+ * Package protected for unit tests.
+ *
+ * @param fixedFormat the fixed format
+ */
+ FixedDateFormat(final FixedFormat fixedFormat) {
+ this.fixedFormat = Objects.requireNonNull(fixedFormat);
+ this.timeSeparatorChar = fixedFormat.timeSeparatorChar;
+ this.timeSeparatorLength = fixedFormat.timeSeparatorLength;
+ this.millisSeparatorChar = fixedFormat.millisSeparatorChar;
+ this.millisSeparatorLength = fixedFormat.millisSeparatorLength;
+ this.length = fixedFormat.getLength();
+ this.dateLength = fixedFormat.getDatePatternLength();
+ this.fastDateFormat = fixedFormat.getFastDateFormat();
+ }
+
+ public String getFormat() {
+ return fixedFormat.getPattern();
+ }
+
+ // Profiling showed this method is important to log4j performance. Modify with care!
+ // 30 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes)
+ private long millisSinceMidnight(final long now) {
+ if (now >= midnightTomorrow || now < midnightToday) {
+ updateMidnightMillis(now);
+ }
+ return now - midnightToday;
+ }
+
+ private void updateMidnightMillis(final long now) {
+
+ updateCachedDate(now);
+
+ midnightToday = calcMidnightMillis(now, 0);
+ midnightTomorrow = calcMidnightMillis(now, 1);
+ }
+
+ static long calcMidnightMillis(final long time, final int addDays) {
+ final Calendar cal = Calendar.getInstance();
+ cal.setTimeInMillis(time);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.add(Calendar.DATE, addDays);
+ return cal.getTimeInMillis();
+ }
+
+ private void updateCachedDate(final long now) {
+ if (fastDateFormat != null) {
+ final StringBuilder result = fastDateFormat.format(now, new StringBuilder());
+ cachedDate = result.toString().toCharArray();
+ }
+ }
+
+ // Profiling showed this method is important to log4j performance. Modify with care!
+ // 28 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes)
+ public String format(final long time) {
+ final char[] result = new char[length];
+ int written = format(time, result, 0);
+ return new String(result, 0, written);
+ }
+
+ // Profiling showed this method is important to log4j performance. Modify with care!
+ // 31 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes)
+ public int format(final long time, final char[] buffer, final int startPos) {
+ // Calculate values by getting the ms values first and do then
+ // calculate the hour minute and second values divisions.
+
+ // Get daytime in ms: this does fit into an int
+ // int ms = (int) (time % 86400000);
+ final int ms = (int) (millisSinceMidnight(time));
+ writeDate(buffer, startPos);
+ return writeTime(ms, buffer, startPos + dateLength) - startPos;
+ }
+
+ // Profiling showed this method is important to log4j performance. Modify with care!
+ // 22 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes)
+ private void writeDate(final char[] buffer, final int startPos) {
+ if (cachedDate != null) {
+ System.arraycopy(cachedDate, 0, buffer, startPos, dateLength);
+ }
+ }
+
+ // Profiling showed this method is important to log4j performance. Modify with care!
+ // 262 bytes (will be inlined when hot enough: <= -XX:FreqInlineSize=325 bytes on Linux)
+ private int writeTime(int ms, final char[] buffer, int pos) {
+ final int hours = ms / 3600000;
+ ms -= 3600000 * hours;
+
+ final int minutes = ms / 60000;
+ ms -= 60000 * minutes;
+
+ final int seconds = ms / 1000;
+ ms -= 1000 * seconds;
+
+ // Hour
+ int temp = hours / 10;
+ buffer[pos++] = ((char) (temp + '0'));
+
+ // Do subtract to get remainder instead of doing % 10
+ buffer[pos++] = ((char) (hours - 10 * temp + '0'));
+ buffer[pos] = timeSeparatorChar;
+ pos += timeSeparatorLength;
+
+ // Minute
+ temp = minutes / 10;
+ buffer[pos++] = ((char) (temp + '0'));
+
+ // Do subtract to get remainder instead of doing % 10
+ buffer[pos++] = ((char) (minutes - 10 * temp + '0'));
+ buffer[pos] = timeSeparatorChar;
+ pos += timeSeparatorLength;
+
+ // Second
+ temp = seconds / 10;
+ buffer[pos++] = ((char) (temp + '0'));
+ buffer[pos++] = ((char) (seconds - 10 * temp + '0'));
+ buffer[pos] = millisSeparatorChar;
+ pos += millisSeparatorLength;
+
+ // Millisecond
+ temp = ms / 100;
+ buffer[pos++] = ((char) (temp + '0'));
+
+ ms -= 100 * temp;
+ temp = ms / 10;
+ buffer[pos++] = ((char) (temp + '0'));
+
+ ms -= 10 * temp;
+ buffer[pos++] = ((char) (ms + '0'));
+ return pos;
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d8935c8a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/datetime/CustomTimeFormatTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/datetime/CustomTimeFormatTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/datetime/CustomTimeFormatTest.java
deleted file mode 100644
index be674c1..0000000
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/datetime/CustomTimeFormatTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-
-package org.apache.logging.log4j.core.util.datetime;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.logging.log4j.core.util.datetime.CustomTimeFormat.FixedFormat;
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests the CustomTimeFormat class.
- */
-public class CustomTimeFormatTest {
-
- @Test
- public void testFixedFormat_getDatePatternNullIfNoDateInPattern() {
- assertNull(FixedFormat.ABSOLUTE.getDatePattern());
- assertNull(FixedFormat.ABSOLUTE2.getDatePattern());
- }
-
- @Test
- public void testFixedFormat_getDatePatternLengthZeroIfNoDateInPattern() {
- assertEquals(0, FixedFormat.ABSOLUTE.getDatePatternLength());
- assertEquals(0, FixedFormat.ABSOLUTE2.getDatePatternLength());
- }
-
- @Test
- public void testFixedFormat_getFastDateFormatNullIfNoDateInPattern() {
- assertNull(FixedFormat.ABSOLUTE.getFastDateFormat());
- assertNull(FixedFormat.ABSOLUTE2.getFastDateFormat());
- }
-
- @Test
- public void testFixedFormat_getDatePatternReturnsDatePatternIfExists() {
- assertEquals("yyyyMMdd", FixedFormat.COMPACT.getDatePattern());
- assertEquals("yyyy-MM-dd ", FixedFormat.DEFAULT.getDatePattern());
- }
-
- @Test
- public void testFixedFormat_getDatePatternLengthReturnsDatePatternLength() {
- assertEquals("yyyyMMdd".length(), FixedFormat.COMPACT.getDatePatternLength());
- assertEquals("yyyy-MM-dd ".length(), FixedFormat.DEFAULT.getDatePatternLength());
- }
-
- @Test
- public void testFixedFormat_getFastDateFormatNonNullIfDateInPattern() {
- assertNotNull(FixedFormat.COMPACT.getFastDateFormat());
- assertNotNull(FixedFormat.DEFAULT.getFastDateFormat());
- assertEquals("yyyyMMdd", FixedFormat.COMPACT.getFastDateFormat().getPattern());
- assertEquals("yyyy-MM-dd ", FixedFormat.DEFAULT.getFastDateFormat().getPattern());
- }
-
- @Test
- public void testCreateIfSupported_nonNullIfNameMatches() {
- for (final CustomTimeFormat.FixedFormat format : CustomTimeFormat.FixedFormat.values()) {
- final String[] options = {format.name()};
- assertNotNull(format.name(), CustomTimeFormat.createIfSupported(options));
- }
- }
-
- @Test
- public void testCreateIfSupported_nonNullIfPatternMatches() {
- for (final CustomTimeFormat.FixedFormat format : CustomTimeFormat.FixedFormat.values()) {
- final String[] options = {format.getPattern()};
- assertNotNull(format.name(), CustomTimeFormat.createIfSupported(options));
- }
- }
-
- @Test
- public void testCreateIfSupported_nullIfNameDoesNotMatch() {
- final String[] options = {"DEFAULT3"};
- assertNull("DEFAULT3", CustomTimeFormat.createIfSupported(options));
- }
-
- @Test
- public void testCreateIfSupported_nullIfPatternDoesNotMatch() {
- final String[] options = {"y M d H m s"};
- assertNull("y M d H m s", CustomTimeFormat.createIfSupported(options));
- }
-
- @Test
- public void testCreateIfSupported_nullIfOptionsArrayNull() {
- assertNull("null", CustomTimeFormat.createIfSupported((String[]) null));
- }
-
- @Test
- public void testCreateIfSupported_nullIfOptionsArrayHasTwoElements() {
- final String[] options = {CustomTimeFormat.FixedFormat.ABSOLUTE.getPattern(), "+08:00"};
- assertNull("timezone", CustomTimeFormat.createIfSupported(options));
- }
-
- @Test(expected=NullPointerException.class)
- public void testConstructorDisallowsNull() {
- new CustomTimeFormat(null);
- }
-
- @Test
- public void testGetFormatReturnsConstructorFixedFormatPattern() {
- final CustomTimeFormat format = new CustomTimeFormat(CustomTimeFormat.FixedFormat.ABSOLUTE);
- assertSame(CustomTimeFormat.FixedFormat.ABSOLUTE.getPattern(), format.getFormat());
- }
-
- @Test
- public void testFormatLong() {
- final long start = System.currentTimeMillis();
- final long end = start + TimeUnit.HOURS.toMillis(25);
- for (final FixedFormat format : FixedFormat.values()) {
- final SimpleDateFormat simpleDF = new SimpleDateFormat(format.getPattern());
- final CustomTimeFormat customTF = new CustomTimeFormat(format);
- for (long time = start; time < end; time += 12345) {
- final String actual = customTF.format(time);
- final String expected = simpleDF.format(new Date(time));
- assertEquals(format + "/" + time, expected, actual);
- }
- }
- }
-
- @Test
- public void testFormatLongCharArrayInt() {
- final long start = System.currentTimeMillis();
- final long end = start + TimeUnit.HOURS.toMillis(25);
- final char[] buffer = new char[128];
- for (final FixedFormat format : FixedFormat.values()) {
- final SimpleDateFormat simpleDF = new SimpleDateFormat(format.getPattern());
- final CustomTimeFormat customTF = new CustomTimeFormat(format);
- for (long time = start; time < end; time += 12345) {
- final int length = customTF.format(time, buffer, 23);
- final String actual = new String(buffer, 23, length);
- final String expected = simpleDF.format(new Date(time));
- assertEquals(format + "/" + time, expected, actual);
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d8935c8a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/datetime/FixedDateFormatTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/datetime/FixedDateFormatTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/datetime/FixedDateFormatTest.java
new file mode 100644
index 0000000..dc222e7
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/datetime/FixedDateFormatTest.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.util.datetime;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.logging.log4j.core.util.datetime.FixedDateFormat.FixedFormat;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the FixedDateFormat class.
+ */
+public class FixedDateFormatTest {
+
+ @Test
+ public void testFixedFormat_getDatePatternNullIfNoDateInPattern() {
+ assertNull(FixedFormat.ABSOLUTE.getDatePattern());
+ assertNull(FixedFormat.ABSOLUTE_PERIOD.getDatePattern());
+ }
+
+ @Test
+ public void testFixedFormat_getDatePatternLengthZeroIfNoDateInPattern() {
+ assertEquals(0, FixedFormat.ABSOLUTE.getDatePatternLength());
+ assertEquals(0, FixedFormat.ABSOLUTE_PERIOD.getDatePatternLength());
+ }
+
+ @Test
+ public void testFixedFormat_getFastDateFormatNullIfNoDateInPattern() {
+ assertNull(FixedFormat.ABSOLUTE.getFastDateFormat());
+ assertNull(FixedFormat.ABSOLUTE_PERIOD.getFastDateFormat());
+ }
+
+ @Test
+ public void testFixedFormat_getDatePatternReturnsDatePatternIfExists() {
+ assertEquals("yyyyMMdd", FixedFormat.COMPACT.getDatePattern());
+ assertEquals("yyyy-MM-dd ", FixedFormat.DEFAULT.getDatePattern());
+ }
+
+ @Test
+ public void testFixedFormat_getDatePatternLengthReturnsDatePatternLength() {
+ assertEquals("yyyyMMdd".length(), FixedFormat.COMPACT.getDatePatternLength());
+ assertEquals("yyyy-MM-dd ".length(), FixedFormat.DEFAULT.getDatePatternLength());
+ }
+
+ @Test
+ public void testFixedFormat_getFastDateFormatNonNullIfDateInPattern() {
+ assertNotNull(FixedFormat.COMPACT.getFastDateFormat());
+ assertNotNull(FixedFormat.DEFAULT.getFastDateFormat());
+ assertEquals("yyyyMMdd", FixedFormat.COMPACT.getFastDateFormat().getPattern());
+ assertEquals("yyyy-MM-dd ", FixedFormat.DEFAULT.getFastDateFormat().getPattern());
+ }
+
+ @Test
+ public void testCreateIfSupported_nonNullIfNameMatches() {
+ for (final FixedDateFormat.FixedFormat format : FixedDateFormat.FixedFormat.values()) {
+ final String[] options = {format.name()};
+ assertNotNull(format.name(), FixedDateFormat.createIfSupported(options));
+ }
+ }
+
+ @Test
+ public void testCreateIfSupported_nonNullIfPatternMatches() {
+ for (final FixedDateFormat.FixedFormat format : FixedDateFormat.FixedFormat.values()) {
+ final String[] options = {format.getPattern()};
+ assertNotNull(format.name(), FixedDateFormat.createIfSupported(options));
+ }
+ }
+
+ @Test
+ public void testCreateIfSupported_nullIfNameDoesNotMatch() {
+ final String[] options = {"DEFAULT3"};
+ assertNull("DEFAULT3", FixedDateFormat.createIfSupported(options));
+ }
+
+ @Test
+ public void testCreateIfSupported_nullIfPatternDoesNotMatch() {
+ final String[] options = {"y M d H m s"};
+ assertNull("y M d H m s", FixedDateFormat.createIfSupported(options));
+ }
+
+ @Test
+ public void testCreateIfSupported_defaultIfOptionsArrayNull() {
+ final FixedDateFormat fmt = FixedDateFormat.createIfSupported((String[]) null);
+ assertEquals(FixedFormat.DEFAULT.getPattern(), fmt.getFormat());
+ }
+
+ @Test
+ public void testCreateIfSupported_defaultIfOptionsArrayEmpty() {
+ final FixedDateFormat fmt = FixedDateFormat.createIfSupported(new String[0]);
+ assertEquals(FixedFormat.DEFAULT.getPattern(), fmt.getFormat());
+ }
+
+ @Test
+ public void testCreateIfSupported_defaultIfOptionsArrayWithSingleNullElement() {
+ final FixedDateFormat fmt = FixedDateFormat.createIfSupported(new String[1]);
+ assertEquals(FixedFormat.DEFAULT.getPattern(), fmt.getFormat());
+ }
+
+ @Test
+ public void testCreateIfSupported_nullIfOptionsArrayHasTwoElements() {
+ final String[] options = {FixedDateFormat.FixedFormat.ABSOLUTE.getPattern(), "+08:00"};
+ assertNull("timezone", FixedDateFormat.createIfSupported(options));
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void testConstructorDisallowsNull() {
+ new FixedDateFormat(null);
+ }
+
+ @Test
+ public void testGetFormatReturnsConstructorFixedFormatPattern() {
+ final FixedDateFormat format = new FixedDateFormat(FixedDateFormat.FixedFormat.ABSOLUTE);
+ assertSame(FixedDateFormat.FixedFormat.ABSOLUTE.getPattern(), format.getFormat());
+ }
+
+ @Test
+ public void testFormatLong() {
+ final long now = System.currentTimeMillis();
+ final long start = now - TimeUnit.HOURS.toMillis(25);
+ final long end = now + TimeUnit.HOURS.toMillis(25);
+ for (final FixedFormat format : FixedFormat.values()) {
+ final SimpleDateFormat simpleDF = new SimpleDateFormat(format.getPattern());
+ final FixedDateFormat customTF = new FixedDateFormat(format);
+ for (long time = start; time < end; time += 12345) {
+ final String actual = customTF.format(time);
+ final String expected = simpleDF.format(new Date(time));
+ assertEquals(format + "/" + time, expected, actual);
+ }
+ }
+ }
+
+ @Test
+ public void testFormatLong_goingBackInTime() {
+ final long now = System.currentTimeMillis();
+ final long start = now - TimeUnit.HOURS.toMillis(25);
+ final long end = now + TimeUnit.HOURS.toMillis(25);
+ for (final FixedFormat format : FixedFormat.values()) {
+ final SimpleDateFormat simpleDF = new SimpleDateFormat(format.getPattern());
+ final FixedDateFormat customTF = new FixedDateFormat(format);
+ for (long time = end; time > start; time -= 12345) {
+ final String actual = customTF.format(time);
+ final String expected = simpleDF.format(new Date(time));
+ assertEquals(format + "/" + time, expected, actual);
+ }
+ }
+ }
+
+ @Test
+ public void testFormatLongCharArrayInt() {
+ final long now = System.currentTimeMillis();
+ final long start = now - TimeUnit.HOURS.toMillis(25);
+ final long end = now + TimeUnit.HOURS.toMillis(25);
+ final char[] buffer = new char[128];
+ for (final FixedFormat format : FixedFormat.values()) {
+ final SimpleDateFormat simpleDF = new SimpleDateFormat(format.getPattern());
+ final FixedDateFormat customTF = new FixedDateFormat(format);
+ for (long time = start; time < end; time += 12345) {
+ final int length = customTF.format(time, buffer, 23);
+ final String actual = new String(buffer, 23, length);
+ final String expected = simpleDF.format(new Date(time));
+ assertEquals(format + "/" + time, expected, actual);
+ }
+ }
+ }
+
+ @Test
+ public void testFormatLongCharArrayInt_goingBackInTime() {
+ final long now = System.currentTimeMillis();
+ final long start = now - TimeUnit.HOURS.toMillis(25);
+ final long end = now + TimeUnit.HOURS.toMillis(25);
+ final char[] buffer = new char[128];
+ for (final FixedFormat format : FixedFormat.values()) {
+ final SimpleDateFormat simpleDF = new SimpleDateFormat(format.getPattern());
+ final FixedDateFormat customTF = new FixedDateFormat(format);
+ for (long time = end; time > start; time -= 12345) {
+ final int length = customTF.format(time, buffer, 23);
+ final String actual = new String(buffer, 23, length);
+ final String expected = simpleDF.format(new Date(time));
+ assertEquals(format + "/" + time, expected, actual);
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d8935c8a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadsafeDateFormatBenchmark.java
----------------------------------------------------------------------
diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadsafeDateFormatBenchmark.java b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadsafeDateFormatBenchmark.java
index ff06520..d6865a3 100644
--- a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadsafeDateFormatBenchmark.java
+++ b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadsafeDateFormatBenchmark.java
@@ -22,7 +22,7 @@ import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-import org.apache.logging.log4j.core.util.datetime.CustomTimeFormat;
+import org.apache.logging.log4j.core.util.datetime.FixedDateFormat;
import org.apache.logging.log4j.core.util.datetime.FastDateFormat;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -50,50 +50,50 @@ public class ThreadsafeDateFormatBenchmark {
private final Date date = new Date();
private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
- private final ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>() {
+ private final ThreadLocal<SimpleDateFormat> threadLocalSDFormat = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("HH:mm:ss.SSS");
}
};
- private final ThreadLocal<Formatter> localFormat = new ThreadLocal<Formatter>() {
+ private final ThreadLocal<FormatterSimple> threadLocalCachedSDFormat = new ThreadLocal<FormatterSimple>() {
@Override
- protected Formatter initialValue() {
- return new Formatter();
+ protected FormatterSimple initialValue() {
+ return new FormatterSimple();
}
};
- private final FastDateFormat fastFormat = FastDateFormat.getInstance("HH:mm:ss.SSS");
- private final CustomTimeFormat customFormat = CustomTimeFormat.createIfSupported("HH:mm:ss.SSS");
- private final CustomFormatReuseBuffer customFormatReuseBuffer = new CustomFormatReuseBuffer();
+ private final FastDateFormat fastDateFormat = FastDateFormat.getInstance("HH:mm:ss.SSS");
+ private final FixedDateFormat fixedDateFormat = FixedDateFormat.createIfSupported("HH:mm:ss.SSS");
+ private final FormatterFixedReuseBuffer formatFixedReuseBuffer = new FormatterFixedReuseBuffer();
- private class CurrentTime {
+ private class CachedTimeFastFormat {
private final long timestamp;
private final String formatted;
- public CurrentTime(final long timestamp) {
+ public CachedTimeFastFormat(final long timestamp) {
this.timestamp = timestamp;
- this.formatted = fastFormat.format(timestamp);
+ this.formatted = fastDateFormat.format(timestamp);
}
}
- private class CustomCurrentTime {
+ private class CachedTimeFixedFmt {
private final long timestamp;
private final String formatted;
- public CustomCurrentTime(final long timestamp) {
+ public CachedTimeFixedFmt(final long timestamp) {
this.timestamp = timestamp;
- this.formatted = customFormat.format(timestamp);
+ this.formatted = fixedDateFormat.format(timestamp);
}
}
- private class Formatter {
+ private class FormatterSimple {
private final SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss.SSS");
private long timestamp;
private String formatted;
- public Formatter() {
+ public FormatterSimple() {
this.timestamp = 0;
}
@@ -106,8 +106,8 @@ public class ThreadsafeDateFormatBenchmark {
}
}
- private class CustomFormatReuseBuffer {
- private final CustomTimeFormat customFormat = CustomTimeFormat.createIfSupported("HH:mm:ss.SSS");
+ private class FormatterFixedReuseBuffer {
+ private final FixedDateFormat customFormat = FixedDateFormat.createIfSupported("HH:mm:ss.SSS");
private long timestamp;
private String formatted;
private final ThreadLocal<char[]> reusableBuffer = new ThreadLocal<char[]>() {
@@ -117,7 +117,7 @@ public class ThreadsafeDateFormatBenchmark {
}
};
- public CustomFormatReuseBuffer() {
+ public FormatterFixedReuseBuffer() {
this.timestamp = 0;
}
@@ -135,8 +135,8 @@ public class ThreadsafeDateFormatBenchmark {
private final long currentTimestamp = 0;
private String cachedTime = null;
- private final AtomicReference<CurrentTime> currentTime = new AtomicReference<>(new CurrentTime(System.currentTimeMillis()));
- private final AtomicReference<CustomCurrentTime> customCurrentTime = new AtomicReference<>(new CustomCurrentTime(System.currentTimeMillis()));
+ private final AtomicReference<CachedTimeFastFormat> cachedTimeFastFmt = new AtomicReference<>(new CachedTimeFastFormat(System.nanoTime()));
+ private final AtomicReference<CachedTimeFixedFmt> cachedTimeFixedFmt = new AtomicReference<>(new CachedTimeFixedFmt(System.nanoTime()));
public static void main(final String[] args) {
}
@@ -151,7 +151,7 @@ public class ThreadsafeDateFormatBenchmark {
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public String synchronizedSimpleDateFmt() {
- final long timestamp = System.currentTimeMillis();
+ final long timestamp = System.nanoTime();
synchronized (simpleDateFormat) {
if (timestamp != currentTimestamp) {
cachedTime = simpleDateFormat.format(date);
@@ -164,52 +164,52 @@ public class ThreadsafeDateFormatBenchmark {
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public String threadLocalSimpleDateFmt() {
- final long timestamp = System.currentTimeMillis();
- return threadLocal.get().format(timestamp);
+ final long timestamp = System.nanoTime();
+ return threadLocalSDFormat.get().format(timestamp);
}
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public String cachedThrdLocalSimpleDateFmt() {
- final long timestamp = System.currentTimeMillis();
- return localFormat.get().format(timestamp);
+ final long timestamp = System.nanoTime();
+ return threadLocalCachedSDFormat.get().format(timestamp);
}
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public String cachedThrdLocalCustomFormat() {
- final long timestamp = System.currentTimeMillis();
- return customFormatReuseBuffer.format(timestamp);
+ final long timestamp = System.nanoTime();
+ return formatFixedReuseBuffer.format(timestamp);
}
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
- public String fastFormat() {
- return fastFormat.format(System.currentTimeMillis());
+ public String fastDateFormat() {
+ return fastDateFormat.format(System.nanoTime());
}
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
- public String customFormat() {
- return customFormat.format(System.currentTimeMillis());
+ public String fixedDateFormat() {
+ return fixedDateFormat.format(System.nanoTime());
}
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public String atomicFastFormat() {
- final long timestamp = System.currentTimeMillis();
- final CurrentTime current = currentTime.get();
+ final long timestamp = System.nanoTime();
+ final CachedTimeFastFormat current = cachedTimeFastFmt.get();
if (timestamp != current.timestamp) {
- final CurrentTime newTime = new CurrentTime(timestamp);
- if (currentTime.compareAndSet(current, newTime)) {
+ final CachedTimeFastFormat newTime = new CachedTimeFastFormat(timestamp);
+ if (cachedTimeFastFmt.compareAndSet(current, newTime)) {
return newTime.formatted;
} else {
- return currentTime.get().formatted;
+ return cachedTimeFastFmt.get().formatted;
}
}
@@ -219,15 +219,15 @@ public class ThreadsafeDateFormatBenchmark {
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
- public String atomicCustomFormat() {
- final long timestamp = System.currentTimeMillis();
- final CustomCurrentTime current = customCurrentTime.get();
+ public String atomicFixedFormat() {
+ final long timestamp = System.nanoTime();
+ final CachedTimeFixedFmt current = cachedTimeFixedFmt.get();
if (timestamp != current.timestamp) {
- final CustomCurrentTime newTime = new CustomCurrentTime(timestamp);
- if (customCurrentTime.compareAndSet(current, newTime)) {
+ final CachedTimeFixedFmt newTime = new CachedTimeFixedFmt(timestamp);
+ if (cachedTimeFixedFmt.compareAndSet(current, newTime)) {
return newTime.formatted;
} else {
- return customCurrentTime.get().formatted;
+ return cachedTimeFixedFmt.get().formatted;
}
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d8935c8a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/TimeFormatBenchmark.java
----------------------------------------------------------------------
diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/TimeFormatBenchmark.java b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/TimeFormatBenchmark.java
index 1d6f4ff..74e76f7 100644
--- a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/TimeFormatBenchmark.java
+++ b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/TimeFormatBenchmark.java
@@ -23,7 +23,7 @@ import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;
-import org.apache.logging.log4j.core.util.datetime.CustomTimeFormat;
+import org.apache.logging.log4j.core.util.datetime.FixedDateFormat;
import org.apache.logging.log4j.core.util.datetime.FastDateFormat;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -56,7 +56,7 @@ public class TimeFormatBenchmark {
}
};
FastDateFormat fastDateFormat = FastDateFormat.getInstance("HH:mm:ss.SSS");
- CustomTimeFormat customTimeFormat = CustomTimeFormat.createIfSupported(new String[]{"ABSOLUTE"});
+ FixedDateFormat fixedDateFormat = FixedDateFormat.createIfSupported(new String[]{"ABSOLUTE"});
volatile long midnightToday = 0;
volatile long midnightTomorrow = 0;
@@ -87,8 +87,8 @@ public class TimeFormatBenchmark {
}
public static void main(final String[] args) {
- System.out.println(new TimeFormatBenchmark().customBitFiddlingReuseCharArray(new BufferState()));
- System.out.println(new TimeFormatBenchmark().customFormatReuseStringBuilder(new BufferState()));
+ System.out.println(new TimeFormatBenchmark().fixedBitFiddlingReuseCharArray(new BufferState()));
+ System.out.println(new TimeFormatBenchmark().fixedFormatReuseStringBuilder(new BufferState()));
}
@Benchmark
@@ -117,7 +117,7 @@ public class TimeFormatBenchmark {
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
- public String customBitFiddlingReuseCharArray(final BufferState state) {
+ public String fixedBitFiddlingReuseCharArray(final BufferState state) {
final int len = formatCharArrayBitFiddling(System.currentTimeMillis(), state.charArray, 0);
return new String(state.charArray, 0, len);
}
@@ -125,22 +125,22 @@ public class TimeFormatBenchmark {
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
- public String customTimeFormatCreateNewCharArray(final BufferState state) {
- return customTimeFormat.format(System.currentTimeMillis());
+ public String fixedDateFormatCreateNewCharArray(final BufferState state) {
+ return fixedDateFormat.format(System.currentTimeMillis());
}
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
- public String customTimeFormatReuseCharArray(final BufferState state) {
- final int len = customTimeFormat.format(System.currentTimeMillis(), state.charArray, 0);
+ public String fixedDateFormatReuseCharArray(final BufferState state) {
+ final int len = fixedDateFormat.format(System.currentTimeMillis(), state.charArray, 0);
return new String(state.charArray, 0, len);
}
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
- public String customFormatReuseStringBuilder(final BufferState state) {
+ public String fixedFormatReuseStringBuilder(final BufferState state) {
state.stringBuilder.setLength(0);
formatStringBuilder(System.currentTimeMillis(), state.stringBuilder);
return new String(state.stringBuilder);