Hi Andrew,
Nice! I'll check in the code asap. I don't see a need for synchronizing on previousTimeLock because layout objects are not shared and can be attached to only one appender. The doAppend method in AppenderSkeleton is synchronized and will protect against any threading surprises... Does that make sense? Cheers, 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: <mailto:[EMAIL PROTECTED]> >For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> -- Ceki Gülcü - http://qos.ch -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>