开发者

How can this src vs. build tree timestamp comparison be faster?

for n in `cd src; find . -name "*.java"; cd -`;
  do a=`echo $n | cut -d '.' -f2`;
  if [[ src/$a.java -nt build/$a.class ]];
    then echo src/$a.java;
  fi;
done

It lists all the java files in the src tree; then for each one, it removes the suffix ".java" (cut -d '.' -f2 because find . output is prefixed with .). It then uses -nt to test if the java file in the src tree is newer than the corresponding class file in the build tree; if it is newer, it is output. [javac can then use this to compile only the needed src files, instead of using ant or make]

The problem is that it is too slow, taking about 275ms. How to make it faster?

Or is there a faste开发者_如何转开发r way to do this in bash? I can't see how to do it with find, diff, rsync nor make (which doesn't seem to traverse trees automatically, and needs explicitly listed source files).


try this:

for f in src/*.java; do 
  file=`basename $f`; 
  if [[ src/$file -nt build/${file//.java/} ]]; then 
     echo src/$file; 
  fi; 
done 


I don't know if this structure would be any faster, but it might be worth a try:

while read n
do
     # capture the basename all at once
     [[ $n =~ src/(.*)\.java ]]   # escape the parentheses for Bash < 3.2 (or thereabouts)
     [[ $n -nt "build/${BASH_REMATCH[1]}.class" ]] && echo $n
done < <(find src -name "*.java")

The while form probably won't provide any boost. The collapsed if may. The regex might provide a small contribution.

As you've found out, eliminating a call to cut has made the biggest difference.


ant performs smart building logic, it will not build a class unless the source was modified.

You might also like to look into scons which is not a native Java build tool but is very handy at compiling efficient complex build trees and does have java builder as well.


Adopting kon's approach to the filename munging, the speed improves from 320ms to 45ms on average. Thanks kon!

for n in `cd src; find . -name "*.java"; cd -`; do
  if [[ src/$n -nt build/${n/.java/.class} ]];
     then echo src/$n;
  fi;
done

The original is a bit slower now (was 275ms; now 320ms); I don't know why. I'm using the same line. Maybe different system sources after playing a video.

EDIT re rst's comment: mangling the "src/" away instead of cd src; ... cd -;. Note that both $n and $n2 are used [you can't nest the ${var/A/B} construct, can you?]

for n in `find src -name "*.java"`; do
  n2=${n/src/}
  if [[ $n -nt build/${n2/.java/.class} ]];
     then echo $n;
  fi;
done
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜