Overall Log4J logging speed with typical ISO date format strings
(like "%p %t %d{ISO8601} %c %m%n") is roughly 50% faster 
with this date string caching optimization (at least on
my JDK 1.3/Windows machine).

This puts typical logging using %d{ISO8601} closer to 
as %r (relative) timings.

Although I've tested it and it seems fine, more testing never hurts.

diff -u made against
jakarta-log4j-1.2alpha6/src/java/org/apache/log4j/helpers/ISO8601DateFormat.java

-Andrew Vajoczki

--- ISO8601DateFormat.java.orig Thu Jan 17 19:52:28 2002
+++ ISO8601DateFormat.java      Fri Jan 18 12:20:26 2002
@@ -41,6 +41,10 @@
   ISO8601DateFormat(TimeZone timeZone) {
     super(timeZone);
   }
+
+  static private Object lastTimeLock = new Object();;
+  static private long   lastTime;
+  static private char[] lastTimeString = new char[20];
   
   /**
      Appends a date in the format "YYYY-mm-dd HH:mm:ss,SSS"
@@ -52,37 +56,87 @@
   StringBuffer format(Date date, StringBuffer sbuf,
                      FieldPosition fieldPosition) {
 
-    calendar.setTime(date);      
-
-    int year =  calendar.get(Calendar.YEAR);
-    sbuf.append(year);
+    long now = date.getTime();
+    int millis = (int)(now % 1000);
 
-    String month;
-    switch(calendar.get(Calendar.MONTH)) {
-    case Calendar.JANUARY: month = "-01-"; break;      
-    case Calendar.FEBRUARY: month = "-02-";  break;     
-    case Calendar.MARCH: month = "-03-"; break;      
-    case Calendar.APRIL: month = "-04-";  break;     
-    case Calendar.MAY: month = "-05-"; break;      
-    case Calendar.JUNE: month = "-06-";  break;     
-    case Calendar.JULY: month = "-07-"; break;      
-    case Calendar.AUGUST: month = "-08-";  break;     
-    case Calendar.SEPTEMBER: month = "-09-"; break;      
-    case Calendar.OCTOBER: month = "-10-"; break;      
-    case Calendar.NOVEMBER: month = "-11-";  break;           
-    case Calendar.DECEMBER: month = "-12-";  break;
-    default: month = "-NA-"; break;
+    synchronized (lastTimeLock) {
+      if ((now - millis) != lastTime) {
+        // 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 year =  calendar.get(Calendar.YEAR);
+        sbuf.append(year);
+         
+        String month;
+        switch(calendar.get(Calendar.MONTH)) {
+        case Calendar.JANUARY: month = "-01-"; break;      
+        case Calendar.FEBRUARY: month = "-02-";  break;     
+        case Calendar.MARCH: month = "-03-"; break;      
+        case Calendar.APRIL: month = "-04-";  break;     
+        case Calendar.MAY: month = "-05-"; break;      
+        case Calendar.JUNE: month = "-06-";  break;     
+        case Calendar.JULY: month = "-07-"; break;      
+        case Calendar.AUGUST: month = "-08-";  break;     
+        case Calendar.SEPTEMBER: month = "-09-"; break;      
+        case Calendar.OCTOBER: month = "-10-"; break;      
+        case Calendar.NOVEMBER: month = "-11-";  break;           
+        case Calendar.DECEMBER: month = "-12-";  break;
+        default: month = "-NA-"; break;
+        }
+        sbuf.append(month);
+         
+        int day = calendar.get(Calendar.DAY_OF_MONTH);
+        if(day < 10) 
+          sbuf.append('0');
+        sbuf.append(day);
+         
+        sbuf.append(' ');    
+
+        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(), lastTimeString, 0);
+        lastTime = now - millis;
+      } 
+      else {
+        sbuf.append(lastTimeString);
+      } 
     }
-    sbuf.append(month);
-
-    int day = calendar.get(Calendar.DAY_OF_MONTH);
-    if(day < 10) 
-      sbuf.append('0');
-    sbuf.append(day);
-
-    sbuf.append(' ');    
-    return super.format(date, sbuf, fieldPosition);
-  }
+    
+    if (millis < 100)
+      sbuf.append('0'); 
+    if (millis < 10)
+      sbuf.append('0'); 
+    
+    sbuf.append(millis);
+    return sbuf;
+  } 
 
   /**
     This method does not do anything but return <code>null</code>.
@@ -92,3 +146,4 @@
     return null;
   }  
 }
+

Attachment: ISO8601DateFormat.java.diff.gz
Description: GNU Zip compressed data

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to