You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by Ceki Gülcü <ce...@qos.ch> on 2002/02/17 22:51:06 UTC

Re: [PATCH] improved logging performance for some Log4J date formats

Andrew,

Your patches have been incorporated. As mentioned previously
synchronization is not necessary so I removed it. In addition, the
separator for milliseconds remains the ',' character as specified by
the ISO8601 standard.

Thanks again for a useful patch. Ceki


At 22:42 17.01.2002 -0500, you wrote:
>This patch significantly improves the logging performance
>of the AbsoluteTimeDateFormat class (a.k.a. "%d{ABSOLUTE}"),
>and indirectly ISO8601DateFormat ("%d{ISO8601}")
>and DateTimeDateFormat (%d{"DATE"}).
>
>The "HH:mm:ss," time string (less the "SSS" milliseconds portion)
>is cached and reused as long as the second does not change.
>Since many thousands of events can be logged each
>second, considerable CPU time can be saved by not recalculating
>the "HH:mm:ss," portion of the time string each time.
>In tests using JDK 1.3/Windows I've seen an overall log4j
>logging speed improvement of 10% to 50% depending on the date
>format used. Other Log4J date formatting classes could be
>changed to employ the same optimization.  I'll leave it to someone
>else, since I don't use the other date formats.
>
>The method DecimalFormatSymbols.getDecimalSeparator()
>was also used instead of the previously hard coded ","
>character for the decimal point symbol in your machine's locale
>("." in my case).
>
>This diff was made against
>jakarta-log4j-1.2alpha6/src/java/org/apache/log4j/helpers/AbsoluteTimeDateFormat.java
>
>-Andrew Vajoczki
>
>--- AbsoluteTimeDateFormat.java.orig    Thu Jan 17 18:16:48 2002
>+++ AbsoluteTimeDateFormat.java Thu Jan 17 21:20:14 2002
>@@ -56,7 +56,11 @@
>    AbsoluteTimeDateFormat(TimeZone timeZone) {
>      setCalendar(Calendar.getInstance(timeZone));
>    }
>-
>+
>+  private static Object previousTimeLock = new Object();
>+  private static long   previousTime;
>+  private static char[] previousTimeWithoutMillis = new char[9]; // 
>"HH:mm:ss."
>+
>    /**
>       Appends to <code>sbuf</code> the time in the format
>       "HH:mm:ss,SSS" for example, "15:49:37,459"
>@@ -69,32 +73,52 @@
>    StringBuffer format(Date date, StringBuffer sbuf,
>                       FieldPosition fieldPosition) {
>
>-    // We use a previously instantiated Date object to avoid the needless
>-    // creation of temporary objects. This saves a few micro-secs.
>-    calendar.setTime(date);
>-
>-    int hour = calendar.get(Calendar.HOUR_OF_DAY);
>-    if(hour < 10) {
>-      sbuf.append('0');
>-    }
>-    sbuf.append(hour);
>-    sbuf.append(':');
>-
>-    int mins = calendar.get(Calendar.MINUTE);
>-    if(mins < 10) {
>-      sbuf.append('0');
>-    }
>-    sbuf.append(mins);
>-    sbuf.append(':');
>-
>-    int secs = calendar.get(Calendar.SECOND);
>-    if(secs < 10) {
>-      sbuf.append('0');
>-    }
>-    sbuf.append(secs);
>-    sbuf.append(',');
>+    long now = date.getTime();
>+    int millis = (int)(now % 1000);
>+
>+    synchronized (previousTimeLock) {
>+      if ((now - millis) != previousTime) {
>+        // We reach this point at most once per second
>+        // across all threads instead of each time format()
>+        // is called. This saves considerable CPU time.
>+
>+        calendar.setTime(date);
>+
>+        int start = sbuf.length();
>+
>+        int hour = calendar.get(Calendar.HOUR_OF_DAY);
>+        if(hour < 10) {
>+          sbuf.append('0');
>+        }
>+        sbuf.append(hour);
>+        sbuf.append(':');
>+
>+        int mins = calendar.get(Calendar.MINUTE);
>+        if(mins < 10) {
>+          sbuf.append('0');
>+        }
>+        sbuf.append(mins);
>+        sbuf.append(':');
>+
>+        int secs = calendar.get(Calendar.SECOND);
>+        if(secs < 10) {
>+          sbuf.append('0');
>+        }
>+        sbuf.append(secs);
>+
>+        // use current locale's decimal separator
>+        sbuf.append(new 
>java.text.DecimalFormatSymbols().getDecimalSeparator());
>+
>+        // store the time string for next time to avoid recomputation
>+        sbuf.getChars(start, sbuf.length(), previousTimeWithoutMillis, 0);
>+
>+        previousTime = now - millis;
>+      }
>+      else {
>+        sbuf.append(previousTimeWithoutMillis);
>+      }
>+    }
>
>-    int millis = calendar.get(Calendar.MILLISECOND);
>      if(millis < 100)
>        sbuf.append('0');
>      if(millis < 10)


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>