Just ran Cocoon build under optimize it. Not the clean build, but second one, when there is nothing to do. It took 6 minutes on 1.6GHz P4 desktop box. Guess where all this time has been spent? Logging!

45.26%: Project.fireMessageLoggedEvent() method


Made a quick hack of Project, replaced Vector of BuildListeners with BuildListener[]. Build took 5 minutes.


32.1%: Project.fireMessageLoggedEvent() method

Next hotspot is:
3.78%: DefaultLogger.printMessage
And, after some xerces classes, comes DirectoryScanner - the one who is doing the actual work:
2.2%: DirectoryScanner.scandir



Does somebody know anybody working on Ant logging system? Is Ant 1.6 better in this regard?


PS Removing synchronized() in this method gives even better results: build runs 3 minutes, 43 seconds and fireMessageLoggedEvent method takes just 9.5% of total execution time

PPS Hacked version of Ant-1.5.3's Project.java attached for curious folks

Vadim

Index: src/main/org/apache/tools/ant/Project.java
===================================================================
RCS file: /home/cvspublic/ant/src/main/org/apache/tools/ant/Project.java,v
retrieving revision 1.108.2.12
diff -u -r1.108.2.12 Project.java
--- src/main/org/apache/tools/ant/Project.java  17 Feb 2003 14:21:12 -0000      
1.108.2.12
+++ src/main/org/apache/tools/ant/Project.java  15 Aug 2003 21:26:28 -0000
@@ -198,7 +198,7 @@
     private File baseDir;
 
     /** List of listeners to notify of build events. */
-    private Vector listeners = new Vector();
+    private BuildListener[] listeners = new BuildListener[0];
 
     /**
      * The Ant core classloader - may be <code>null</code> if using
@@ -347,7 +347,13 @@
      *                 Must not be <code>null</code>.
      */
     public void addBuildListener(BuildListener listener) {
-        listeners.addElement(listener);
+        synchronized (this) {
+            int n = listeners.length;
+            BuildListener[] newListeners = new BuildListener[n + 1];
+            System.arraycopy(listeners, 0, newListeners, 0, n);
+            newListeners[n] = listener;
+            listeners = newListeners;
+        }
     }
 
     /**
@@ -358,7 +364,23 @@
      *                 Should not be <code>null</code>.
      */
     public void removeBuildListener(BuildListener listener) {
-        listeners.removeElement(listener);
+        synchronized (this) {
+            int n = listeners.length;
+            int m = 0;
+            for (int i = 0; i < n; i++) {
+                if (listeners[i] != listener && !listeners[i].equals(listener)) {
+                    m++;
+                }
+            }
+            BuildListener[] newListeners = new BuildListener[m];
+            m = 0;
+            for (int i = 0; i < n; i++) {
+                if (listeners[i] != listener && !listeners[i].equals(listener)) {
+                    newListeners[m++] = listeners[i];
+                }
+            }
+            listeners = newListeners;
+        }
     }
 
     /**
@@ -367,7 +389,11 @@
      * @return a list of build listeners for the project
      */
     public Vector getBuildListeners() {
-        return (Vector) listeners.clone();
+        Vector v = new Vector(listeners.length);
+        for (int i = 0; i < listeners.length; i++) {
+            v.add(listeners[i]);
+        }
+        return v;
     }
 
     /**
@@ -987,7 +1013,7 @@
      *                  Must not be <code>null</code>.
      */
     public void addDataTypeDefinition(String typeName, Class typeClass) {
-        synchronized(dataClassDefinitions) {
+        synchronized (dataClassDefinitions) {
             Class old = (Class) dataClassDefinitions.get(typeName);
             if (null != old) {
                 if (old.equals(typeClass)) {
@@ -2003,20 +2029,17 @@
     private void fireMessageLoggedEvent(BuildEvent event, String message,
                                         int priority) {
         event.setMessage(message, priority);
-        Vector listeners = getBuildListeners();
-        synchronized(this) {
-            if (loggingMessage) {
-                throw new BuildException("Listener attempted to access " 
-                    + (priority == MSG_ERR ? "System.err" : "System.out") 
-                    + " - infinite loop terminated");
-            }
-            loggingMessage = true;                
-            for (int i = 0; i < listeners.size(); i++) {
-                BuildListener listener = (BuildListener) listeners.elementAt(i);
-                listener.messageLogged(event);
-            }
-            loggingMessage = false;
+        if (loggingMessage) {
+            throw new BuildException("Listener attempted to access "
+                + (priority == MSG_ERR ? "System.err" : "System.out")
+                + " - infinite loop terminated");
+        }
+        loggingMessage = true;
+        BuildListener[] listeners = this.listeners;
+        for (int i = 0; i < listeners.length; i++) {
+            listeners[i].messageLogged(event);
         }
+        loggingMessage = false;
     }
 
     /**
@@ -2089,6 +2112,4 @@
     public Task getThreadTask(Thread thread) {
         return (Task) threadTasks.get(thread);
     }
-
-
 }

Reply via email to