It’s hard for me to argue that each is better than the other.
Im is working on a mobile application that should do background work with the user's file system. One of the background threads should sweep the entire file system from time to time in order to maintain updated data to the user. Therefore, fearing, I wrote an iterative algorithm. Today I wrote recursive, for the same work. To my surprise, the iterative algorithm is faster: recursive → 37s, iterative → 34s (works on the same file structure).
Recursive:
private long recursive(File rootFile, long counter) { long duration = 0; sendScanUpdateSignal(rootFile.getAbsolutePath()); if(rootFile.isDirectory()) { File[] files = getChildren(rootFile, MUSIC_FILE_FILTER); for(int i = 0; i < files.length; i++) { duration += recursive(files[i], counter); } if(duration != 0) { dhm.put(rootFile.getAbsolutePath(), duration); updateDurationInUI(rootFile.getAbsolutePath(), duration); } } else if(!rootFile.isDirectory() && checkExtension(rootFile.getAbsolutePath())) { duration = getDuration(rootFile); dhm.put(rootFile.getAbsolutePath(), getDuration(rootFile)); updateDurationInUI(rootFile.getAbsolutePath(), duration); } return counter + duration; }
Iterative: - Iterative depth search with recursive reverse tracing
private void traversal(File file) { int pointer = 0; File[] files; boolean hadMusic = false; long parentTimeCounter = 0; while(file != null) { sendScanUpdateSignal(file.getAbsolutePath()); try { Thread.sleep(Constants.THREADS_SLEEP_CONSTANTS.TRAVERSAL); } catch (InterruptedException e) { e.printStackTrace(); } files = getChildren(file, MUSIC_FILE_FILTER); if(!file.isDirectory() && checkExtension(file.getAbsolutePath())) { hadMusic = true; long duration = getDuration(file); parentTimeCounter = parentTimeCounter + duration; dhm.put(file.getAbsolutePath(), duration); updateDurationInUI(file.getAbsolutePath(), duration); } if(files != null && pointer < files.length) { file = getChildren(file,MUSIC_FILE_FILTER)[pointer]; } else if(files != null && pointer+1 < files.length) { file = files[pointer+1]; pointer++; } else { pointer=0; file = getNextSybling(file, hadMusic, parentTimeCounter); hadMusic = false; parentTimeCounter = 0; } } } private File getNextSybling(File file, boolean hadMusic, long timeCounter) { File result= null;
Confident that the iterative is not elegant, but despite the fact that it is currently implemented for an indefinite period, it is still faster than recursive. And I have better control over it, because I don’t want it to work at full speed and let the garbage collector do its work more often.
In any case, I will not take for granted that one method is better than another and will consider other algorithms that are currently recursive. But at least from the 2 algorithms above, the iterative will be one of the final product.
jfv Oct 19 '13 at 10:55 on 2013-10-19 10:55
source share