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]