United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-8010309 : Improve PlatformLogger.isLoggable performance by direct mapping from an integer to Level

Details
Type:
Bug
Submit Date:
2013-03-19
Status:
Closed
Updated Date:
2013-07-22
Project Name:
JDK
Resolved Date:
2013-03-28
Component:
core-libs
OS:
Sub-Component:
java.util.logging
CPU:
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Backport:
Backport:
Relates:
Relates:

Sub Tasks

Description
The JavaLogger implementation uses a Map<Integer, Object> levelObjects to store mapping between PlatformLogger's levels (int) and JUL Level instances.  The isLoggable(int level) method is highly used by awt implementation and other JDK projects and it leads to many Integer allocations as autoboxing converts the level as int to an Integer instance used by the Map.get() call.

The performance and memory overhead can be reduced simply by a direct mapping from int to Level object and avoid the autoboxing conversion.

See details from http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-March/015264.html

Following is a proposed patch contributed-by: bourges.laurent@gmail.com

# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and \n newlines.
--- PlatformLogger.java (6767)
+++ PlatformLogger.java (6768)
@@ -468,31 +468,13 @@
      * java.util.logging.Logger object.
      */
     static class JavaLogger extends LoggerProxy {
-        /** Note: using Integer keys leads to a lot of new Integer instances !! */
-        private static final Map<Integer, Object> levelObjects = new HashMap<>();
-        /** fastest mapping to Level instances from PlatformLogger level as integer */
-        private static final Object[] fastLevelObjects;
-
-
+        private static final Map<Integer, Object> levelObjects =
+            new HashMap<>();
+
         static {
             if (LoggingSupport.isAvailable()) {
                 // initialize the map to Level objects
                 getLevelObjects();
-
-                // initialize the fastLevelObjects:
-                fastLevelObjects = new Object[] {
-                    LoggingSupport.parseLevel(getLevelName(OFF)),       // 0
-                    LoggingSupport.parseLevel(getLevelName(SEVERE)),    // 1
-                    LoggingSupport.parseLevel(getLevelName(WARNING)),   // 2
-                    LoggingSupport.parseLevel(getLevelName(INFO)),      // 3
-                    LoggingSupport.parseLevel(getLevelName(CONFIG)),    // 4
-                    LoggingSupport.parseLevel(getLevelName(FINE)),      // 5
-                    LoggingSupport.parseLevel(getLevelName(FINER)),     // 6
-                    LoggingSupport.parseLevel(getLevelName(FINEST)),    // 7
-                    LoggingSupport.parseLevel(getLevelName(ALL))        // 8
-                };
-            } else {
-                fastLevelObjects = null; // check null
             }
         }

@@ -515,7 +497,7 @@
             this.javaLogger = LoggingSupport.getLogger(name);
             if (level != 0) {
                 // level has been updated and so set the Logger's level
-                LoggingSupport.setLevel(javaLogger, getLevel(level));
+                LoggingSupport.setLevel(javaLogger, levelObjects.get(level));
             }
         }

@@ -526,11 +508,11 @@
         * not be updated.
         */
         void doLog(int level, String msg) {
-            LoggingSupport.log(javaLogger, getLevel(level), msg);
+            LoggingSupport.log(javaLogger, levelObjects.get(level), msg);
         }

         void doLog(int level, String msg, Throwable t) {
-            LoggingSupport.log(javaLogger, getLevel(level), msg, t);
+            LoggingSupport.log(javaLogger, levelObjects.get(level), msg, t);
         }

         void doLog(int level, String msg, Object... params) {
@@ -544,12 +526,12 @@
             for (int i = 0; i < len; i++) {
                 sparams [i] = String.valueOf(params[i]);
             }
-            LoggingSupport.log(javaLogger, getLevel(level), msg, sparams);
+            LoggingSupport.log(javaLogger, levelObjects.get(level), msg, sparams);
         }

         boolean isEnabled() {
             Object level = LoggingSupport.getLevel(javaLogger);
-            return level == null || level.equals(getLevel(OFF)) == false;
+            return level == null || level.equals(levelObjects.get(OFF)) == false;
         }

         int getLevel() {
@@ -566,34 +548,12 @@

         void setLevel(int newLevel) {
             levelValue = newLevel;
-            LoggingSupport.setLevel(javaLogger, getLevel(newLevel));
+            LoggingSupport.setLevel(javaLogger, levelObjects.get(newLevel));
         }

         public boolean isLoggable(int level) {
-            return LoggingSupport.isLoggable(javaLogger, getLevel(level));
+            return LoggingSupport.isLoggable(javaLogger, levelObjects.get(level));
         }
-
-        /**
-         * Return the corresponding level object (fastest implementation)
-         * @param level PlatformLogger level as primitive integer
-         * @return Object (JUL Level instance)
-         */
-        private static Object getLevel(final int level) {
-            // higher occurences first (finest, fine, finer, info):
-            switch (level) {
-                case FINEST  : return fastLevelObjects[7];
-                case FINE    : return fastLevelObjects[5];
-                case FINER   : return fastLevelObjects[6];
-                case INFO    : return fastLevelObjects[3];
-                case CONFIG  : return fastLevelObjects[4];
-                case WARNING : return fastLevelObjects[2];
-                case SEVERE  : return fastLevelObjects[1];
-                case ALL     : return fastLevelObjects[8];
-                case OFF     : return fastLevelObjects[0];
-                default      : return null;
-            }
-        }
-
     }

     private static String getLevelName(int level) {

                                    

Comments
URL:   http://hg.openjdk.java.net/jdk8/tl/jdk/rev/e433ed08b733
User:  mchung
Date:  2013-03-28 20:16:56 +0000

                                     
2013-03-28
URL:   http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/e433ed08b733
User:  lana
Date:  2013-04-16 20:41:41 +0000

                                     
2013-04-16



Hardware and Software, Engineered to Work Together