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; } } +
ISO8601DateFormat.java.diff.gz
Description: GNU Zip compressed data
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>