Although I did measurements many years ago on the best ways to test for the existence of files, I got a little interested now to update my knowledge, and perhaps most importantly: how does it compare with ASObjC. So, here are my findings:
set f to "/Users/harald/Downloads/aFile"
1. The ugly but often fast method: try -- ~0.2 ms when file exists (f as POSIX file) as alias set flag to true on error -- ~0.3 ms when file does not exist set flag to false end try
2. The Finder method:
tell application "Finder" to set flag to exists (f as POSIX file) -- ~2.5 ms
3. The System Events method:
tell application "System Events" to set flag to f exists -- ~1-2.5 ms if SE is running, otherwise ~150 ms
4. The paragraph shell script ls method: set flag to "aFile" is in (get paragraphs of (do shell script "ls " & quoted form of "/Users/harald/Downloads/")) -- ~14 ms
5. The pure shell script method:
set flag to do shell script "if [[ -e " & (quoted form of f) & " ]]; then echo YES; else echo NO; fi" -- ~12 ms
6. The ASObjC method:
set flag to current application's NSFileManager's defaultManager()'s fileExistsAtPath_(f) -- ~0.17 ms
So the clear winner is ASObjC in terms of speed and brevity! (But it does require ASObjC, so no plain vanilla.) It should also be pretty robust. (But maybe there are cases where the pure shell script method could have some advantage?)
How these timings were done: I used AppleScriptObjC Explorer 2 (and therefore it was necessary to use "as Posix file", otherwise ASObjC will spit). I have found that the best method is to use NSDate. It has a variability of less than 0.01 ms, and is therefore much better than my old tried perl-based method calling hires timers. The following is my precise timing instrument. For flexibility, one can set the number of repetitions, but in the measurements above, it was always set to one. The machine is a MacBook Pro Retina. It requires 10.7+.
set repetitions to 1 set t1 to current application's NSDate's timeIntervalSinceReferenceDate() repeat repetitions times --code to measure end repeat NSLog("Timing: %.3f ms per iteration", millisecSince(t1) / repetitions)
on millisecSince(t1) --HEB set t2 to current application's NSDate's timeIntervalSinceReferenceDate() set compensation to (current application's NSDate's timeIntervalSinceReferenceDate()) - t2 return (t2 - t1 - compensation) * 1000 end millisecSince
--heb |