Author: jglick
Date: Wed Oct  3 16:44:10 2007
New Revision: 581748

URL: http://svn.apache.org/viewvc?rev=581748&view=rev
Log:
Various microoptimizations to reduce I/O load of common tasks, esp. no-op 
<javac> and <depend>.
Many inner loops altered to make just 1-2 system calls rather than 4-5.
You can easily see how wasteful the previous code was, and find the culprits,
by patching r/o java.io.File methods and adding to -Xbootclasspath/p (or use 
AspectJ). E.g.:

public boolean isDirectory() {
  System.err.println("isDirectory: " + this); if (Math.random() < .01) 
Thread.dumpStack();
  // as before...
}

Ant still makes an order of magnitude more system calls to do what seem like 
simple operations
than you would think necessary, but this patch should at least improve the 
situation.

Modified:
    ant/core/trunk/WHATSNEW
    ant/core/trunk/src/main/org/apache/tools/ant/DirectoryScanner.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Rmic.java
    
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
    
ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
    ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java
    ant/core/trunk/src/main/org/apache/tools/ant/util/SourceFileScanner.java

Modified: ant/core/trunk/WHATSNEW
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=581748&r1=581747&r2=581748&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Wed Oct  3 16:44:10 2007
@@ -196,6 +196,10 @@
 
 Other changes:
 --------------
+
+* Various small optimizations speed up common tasks such as <javac> on large
+  filesets, reducing both I/O and CPU usage.
+
 * Profiling logger has been added with basic profiling capabilities.
 
 * <script> now has basic support for JavaFX scripts

Modified: ant/core/trunk/src/main/org/apache/tools/ant/DirectoryScanner.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/DirectoryScanner.java?rev=581748&r1=581747&r2=581748&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/DirectoryScanner.java 
(original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/DirectoryScanner.java Wed Oct  
3 16:44:10 2007
@@ -1065,28 +1065,25 @@
     protected void scandir(File dir, String vpath, boolean fast) {
         if (dir == null) {
             throw new BuildException("dir must not be null.");
-        } else if (!dir.exists()) {
-            throw new BuildException(dir + " doesn't exist.");
-        } else if (!dir.isDirectory()) {
-            throw new BuildException(dir + " is not a directory.");
         }
+        String[] newfiles = dir.list();
+        if (newfiles == null) {
+            if (!dir.exists()) {
+                throw new BuildException(dir + " doesn't exist.");
+            } else if (!dir.isDirectory()) {
+                throw new BuildException(dir + " is not a directory.");
+            } else {
+                throw new BuildException("IO error scanning directory '"
+                                         + dir.getAbsolutePath() + "'");
+            }
+        }
+        scandir(dir, vpath, fast, newfiles);
+    }
+    private void scandir(File dir, String vpath, boolean fast, String[] 
newfiles) {
         // avoid double scanning of directories, can only happen in fast mode
         if (fast && hasBeenScanned(vpath)) {
             return;
         }
-        String[] newfiles = dir.list();
-
-        if (newfiles == null) {
-            /*
-             * two reasons are mentioned in the API docs for File.list
-             * (1) dir is not a directory. This is impossible as
-             *     we wouldn't get here in this case.
-             * (2) an IO error occurred (why doesn't it throw an exception
-             *     then???)
-             */
-            throw new BuildException("IO error scanning directory '"
-                                     + dir.getAbsolutePath() + "'");
-        }
         if (!followSymlinks) {
             Vector noLinks = new Vector();
             for (int i = 0; i < newfiles.length; i++) {
@@ -1112,25 +1109,26 @@
         for (int i = 0; i < newfiles.length; i++) {
             String name = vpath + newfiles[i];
             File file = new File(dir, newfiles[i]);
-            if (file.isDirectory()) {
+            String[] children = file.list();
+            if (children == null) { // probably file
                 if (isIncluded(name)) {
-                    accountForIncludedDir(name, file, fast);
+                    accountForIncludedFile(name, file);
+                } else {
+                    everythingIncluded = false;
+                    filesNotIncluded.addElement(name);
+                }
+            } else { // dir
+                if (isIncluded(name)) {
+                    accountForIncludedDir(name, file, fast, children);
                 } else {
                     everythingIncluded = false;
                     dirsNotIncluded.addElement(name);
                     if (fast && couldHoldIncluded(name)) {
-                        scandir(file, name + File.separator, fast);
+                        scandir(file, name + File.separator, fast, children);
                     }
                 }
                 if (!fast) {
-                    scandir(file, name + File.separator, fast);
-                }
-            } else if (file.isFile()) {
-                if (isIncluded(name)) {
-                    accountForIncludedFile(name, file);
-                } else {
-                    everythingIncluded = false;
-                    filesNotIncluded.addElement(name);
+                    scandir(file, name + File.separator, fast, children);
                 }
             }
         }
@@ -1156,6 +1154,12 @@
         processIncluded(name, file, dirsIncluded, dirsExcluded, 
dirsDeselected);
         if (fast && couldHoldIncluded(name) && !contentsExcluded(name)) {
             scandir(file, name + File.separator, fast);
+        }
+    }
+    private void accountForIncludedDir(String name, File file, boolean fast, 
String[] children) {
+        processIncluded(name, file, dirsIncluded, dirsExcluded, 
dirsDeselected);
+        if (fast && couldHoldIncluded(name) && !contentsExcluded(name)) {
+            scandir(file, name + File.separator, fast, children);
         }
     }
 

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Rmic.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Rmic.java?rev=581748&r1=581747&r2=581748&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Rmic.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Rmic.java Wed Oct  3 
16:44:10 2007
@@ -524,9 +524,15 @@
                 scanDir(baseDir, files, adapter.getMapper());
             } else {
                 // otherwise perform a timestamp comparison - at least
-                scanDir(baseDir, new String[] {
-                        classname.replace('.', File.separatorChar)
-                        + ".class" }, adapter.getMapper());
+                String path = classname.replace('.', File.separatorChar) + 
".class";
+                File f = new File(baseDir, path);
+                if (f.isFile()) {
+                    scanDir(baseDir, new String[] { path }, 
adapter.getMapper());
+                } else {
+                    // Does not exist, so checking whether it is up to date 
makes no sense.
+                    // Compilation will fail later anyway, but tests expect a 
certain output.
+                    compileList.add(classname);
+                }
             }
             int fileCount = compileList.size();
             if (fileCount > 0) {

Modified: 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java?rev=581748&r1=581747&r2=581748&view=diff
==============================================================================
--- 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
 (original)
+++ 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
 Wed Oct  3 16:44:10 2007
@@ -773,18 +773,21 @@
      * Find the source file for a given class
      *
      * @param classname the classname in slash format.
+     * @param sourceFileKnownToExist if not null, a file already known to 
exist (saves call to .exists())
      */
-    private File findSourceFile(String classname) {
-        String sourceFilename = classname + ".java";
+    private File findSourceFile(String classname, File sourceFileKnownToExist) 
{
+        String sourceFilename;
         int innerIndex = classname.indexOf("$");
         if (innerIndex != -1) {
             sourceFilename = classname.substring(0, innerIndex) + ".java";
+        } else {
+            sourceFilename = classname + ".java";
         }
 
         // search the various source path entries
         for (int i = 0; i < srcPathList.length; ++i) {
             File sourceFile = new File(srcPathList[i], sourceFilename);
-            if (sourceFile.exists()) {
+            if (sourceFile.equals(sourceFileKnownToExist) || 
sourceFile.exists()) {
                 return sourceFile;
             }
         }
@@ -812,11 +815,10 @@
         int length = filesInDir.length;
 
         int rootLength = root.getPath().length();
+        File sourceFileKnownToExist = null; // speed optimization
         for (int i = 0; i < length; ++i) {
             File file = new File(dir, filesInDir[i]);
-            if (file.isDirectory()) {
-                addClassFiles(classFileList, file, root);
-            } else if (file.getName().endsWith(".class")) {
+            if (filesInDir[i].endsWith(".class")) {
                 ClassFileInfo info = new ClassFileInfo();
                 info.absoluteFile = file;
                 String relativeName = file.getPath().substring(
@@ -824,8 +826,10 @@
                     file.getPath().length() - ".class".length());
                 info.className
                     = ClassFileUtils.convertSlashName(relativeName);
-                info.sourceFile = findSourceFile(relativeName);
+                info.sourceFile = sourceFileKnownToExist = 
findSourceFile(relativeName, sourceFileKnownToExist);
                 classFileList.addElement(info);
+            } else {
+                addClassFiles(classFileList, file, root);
             }
         }
     }

Modified: 
ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java?rev=581748&r1=581747&r2=581748&view=diff
==============================================================================
--- 
ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java 
(original)
+++ 
ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java 
Wed Oct  3 16:44:10 2007
@@ -615,16 +615,16 @@
      */
     public static boolean isOutOfDate(Resource src, Resource target,
                                       long granularity) {
-        if (!src.isExists()) {
+        long sourceLastModified = src.getLastModified();
+        if (sourceLastModified == 0L) {
+            // Does not exist. Quicker than checking exists() again.
             return false;
         }
-        if (!target.isExists()) {
+        long targetLastModified = target.getLastModified();
+        if (targetLastModified == 0L) {
             return true;
         }
-        if ((src.getLastModified() - granularity) > target.getLastModified()) {
-            return true;
-        }
-        return false;
+        return (sourceLastModified - granularity) > targetLastModified;
     }
 
     /**

Modified: ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java?rev=581748&r1=581747&r2=581748&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java 
(original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java Wed 
Oct  3 16:44:10 2007
@@ -61,17 +61,6 @@
  */
 public class ResourceUtils {
 
-    private static final class Outdated implements ResourceSelector {
-        private Resource control;
-        private long granularity;
-        private Outdated(Resource control, long granularity) {
-            this.control = control;
-            this.granularity = granularity;
-        }
-        public boolean isSelected(Resource r) {
-            return SelectorUtils.isOutOfDate(control, r, granularity);
-        }
-    }
     /** Utilities used for file operations */
     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
@@ -144,7 +133,7 @@
                                                             ResourceCollection 
source,
                                                             FileNameMapper 
mapper,
                                                             ResourceFactory 
targets,
-                                                            long granularity) {
+                                                            final long 
granularity) {
         if (source.size() == 0) {
             logTo.log("No sources found.", Project.MSG_VERBOSE);
             return Resources.NONE;
@@ -154,7 +143,7 @@
 
         Union result = new Union();
         for (Iterator iter = source.iterator(); iter.hasNext();) {
-            Resource sr = (Resource) iter.next();
+            final Resource sr = (Resource) iter.next();
             String srName = sr.getName();
             srName = srName == null
                 ? srName : srName.replace('/', File.separatorChar);
@@ -178,8 +167,16 @@
             }
             //find the out-of-date targets:
             Restrict r = new Restrict();
-            r.add(new And(new ResourceSelector[] {Type.FILE, new Or(
-                new ResourceSelector[] {NOT_EXISTS, new Outdated(sr, 
granularity)})}));
+            r.add(new ResourceSelector() {
+                public boolean isSelected(Resource target) {
+                    /* Extra I/O, probably wasted:
+                    if (target.isDirectory()) {
+                        return false;
+                    }
+                     */
+                    return SelectorUtils.isOutOfDate(sr, target, granularity);
+                }
+            });
             r.add(targetColl);
             if (r.size() > 0) {
                 result.add(sr);

Modified: 
ant/core/trunk/src/main/org/apache/tools/ant/util/SourceFileScanner.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/util/SourceFileScanner.java?rev=581748&r1=581747&r2=581748&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/util/SourceFileScanner.java 
(original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/util/SourceFileScanner.java 
Wed Oct  3 16:44:10 2007
@@ -91,9 +91,12 @@
         this.destDir = destDir;
         Vector v = new Vector();
         for (int i = 0; i < files.length; i++) {
-            File src = FILE_UTILS.resolveFile(srcDir, files[i]);
-            v.addElement(new Resource(files[i], src.exists(),
-                                      src.lastModified(), src.isDirectory()));
+            final String name = files[i];
+            v.addElement(new FileResource(srcDir, name) {
+                public String getName() {
+                    return name;
+                }
+            });
         }
         Resource[] sourceresources = new Resource[v.size()];
         v.copyInto(sourceresources);



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

Reply via email to