"do shell script..." can be very slow compared to AppleScript

Curious about which way was faster for writing to a file, I did this little test (perhaps not fair in some way I don’t see, but comments will no doubt point out my fallacies):

-- using the GetMilliSec OSAX for timing
set the_file to (path to desktop as text) & "text.txt"
set the_file2 to (path to desktop as text) & "text2.txt"
set my_text to "This is line 1"
set my_text2 to "This is line 2"
set the_file to quoted form of POSIX path of the_file
set total to 0
repeat 20 times
	delay 2 -- or the shell script will error finding the file
	set t1 to GetMilliSec
	do shell script "echo " & my_text & " > " & the_file
	do shell script "echo " & my_text2 & " >> " & the_file
	set t2 to GetMilliSec
	try
		set F to open for access the_file2 with write permission
		write my_text & return to F
		write my_text2 to F
		close access F
	on error theGoof
		close access F
		display dialog theGoof
	end try
	set t3 to GetMilliSec
	set total to total + (t2 - t1) / (t3 - t2)
end repeat
total / 20 --> 15.391437728938

This returns the time for each method seperately:

-- using the GetMilliSec OSAX for timing
set the_file to (path to desktop as text) & "text.txt"
set the_file2 to (path to desktop as text) & "text2.txt"
set my_text to "This is line 1"
set my_text2 to "This is line 2"
set the_file to quoted form of POSIX path of the_file
set shell to 0
set vanilla to 0
repeat 20 times
	delay 2 -- or the shell script will error finding the file
	set t1 to GetMilliSec
	do shell script "echo " & my_text & " > " & the_file
	do shell script "echo " & my_text2 & " >> " & the_file
	set t2 to GetMilliSec
	try
		set F to open for access the_file2 with write permission
		write my_text & return to F
		write my_text2 to F
		close access F
	on error theGoof
		close access F
		display dialog theGoof
	end try
	set t3 to GetMilliSec
	set shell to shell + (t2 - t1)
	set vanilla to vanilla + (t3 - t2)
end repeat
{"vanilla: " & vanilla / 20, "shell: " & shell / 20}
--my results: {"vanilla: 9.7", "shell: 70.1"}

Vanilla seems to be about 7 times faster than “echo”

I think it’s probably extremely variable depending on what the system is doing. When I ran your version just now, I got:

{“vanilla: 4.05”, “shell: 50.9”} → 12.5

The bottom line is the same, though - using the AS approach is definitely quicker. The need for the delay confuses me though - is it that the shell script doesn’t close the file immediately (it always does eventually)?

Hi,

so here I am to defend the shell’s honor :wink: I guess most of the “slowliness” of the shell is to be attributed to the overhead of the sending of AppleEvents. A “vanilla shell” approach produces this:

[code]$ time for i in 1…20;do echo This is line 1 > ./file.txt; echo This is line 2 >> ./file.txt;done

real 0m0.004s
user 0m0.000s
sys 0m0.010s
$[/code]
Regards,
danB

Model: iBook g3/800 14"
Browser: Safari 312.3.3
Operating System: Mac OS X (10.3.9)

That was clearly understood at the outset Dan - it’s the link to the shell that seems to crawl, but thanks for illustrating it so aptly.

In my example, things speed up substantially if there’s only one call to do shell script which is why when possible it’s a good idea to set up the script as a variable first and then pass it to the shell.

but it’s not all passing: on my machine, this takes 22 to 25 ms:

set t1 to GetMilliSec
set myScript to "time  for i in 1..20; do echo This is line 1 > /Users/bellac/Desktop/file.txt; echo This is line 2 >> /Users/bellac/Desktop/file.txt; done"
do shell script myScript
set t2 to GetMilliSec
t2 - t1

whereas Dan’s script thus: $ time for i in 1…20; do echo This is line 1 > /path/to/my/Desktop/file.txt; echo This is line 2 >> /path/to/my/Desktop/file.txt; done $ took:

real 0m0.014s
user 0m0.000s
sys 0m0.001s

so the call from my script was adding about 10 ms to the task for one call.

According to Emmanuel’s tests, “do shell script” was faster in Jaguar than in Panther or Tiger (speed decreased).

About read/write commands, I’ve been working in an app called “MacHacha” since OS 9 days, which uses some intensive read/write tasks, and the “cat” (*nix) version isn’t much faster (from the end-user perspective) than AS’s read/write commands. In fact, if we could eliminate osaxen calls (to read/write commands in Standard Additions) speed would be virtually the same (as we descend to machine code thru C and variants).

So, the overhead is allways in apple-event intercommunication (both send and receive), and this overhead is sooooooooooo great in “do shell script” (I think, a true speculation, that AS calls Standard Additions, which inits a shell, which calls whatever *nix tool, which invokes the write method, then writes back output to the shell’s stdout, which is read by Standard Additions, which returns the result to AS).