Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!cbosgd!ihnp4!houxm!whuxl!whuxlm!akgua!gatech!seismo!mcvax!ukc!cstvax!hwcs!chris From: chris@hwcs.UUCP Newsgroups: net.unix-wizards Subject: Re: shell compiler? Message-ID: <796@brahma.cs.hw.AC.UK> Date: Mon, 14-Apr-86 05:37:08 EST Article-I.D.: brahma.796 Posted: Mon Apr 14 05:37:08 1986 Date-Received: Wed, 23-Apr-86 20:07:22 EST References: <96@cstvax.UUCP> Reply-To: chris@cs.hw.AC.UK (Chris Miller) Organization: Computer Science, Heriot-Watt U., Scotland Lines: 82 In article <96@cstvax.UUCP> scott@cstvax.UUCP (Scott Larnach) writes: > ... Would a program which turned a shell >script into an equivalent C program (which would handle i/o >redirections, fork/exec the appropriate commands, etc.) usefully >improve the speed of my scripts? I am fairly sure that if your shell has "test" built in then a simple translation of shell control constructs into C will gain you nothing significant on large scripts, since most of the time is spent doing fork/exec. If you have a "clever" translator that knows about a few common "grep", "sed", "awk" and "ls" usages in shell scripts, and puts them directly into C code without exec-ing the corresponding program, you may gain quite a lot more; I don't really think such a translator would be a very good idea, since it would almost inevitably be large, clumsy and as-hoc (and buggy!). As a very rough and ready estimate to the relative load of interpreting control constructs to path-search and fork/exec, I created the following trivial script, "shtest": #!/bin/sh ECHO="$1" for i in 0 1 2 3 4 5 6 7 8 9 ; do for j in 0 1 2 3 4 5 6 7 8 9 ; do for k in 0 1 2 3 4 5 6 7 8 9 ; do $ECHO $i$j$k done done done the following script, "nul.sh": #!/bin/sh exit 0 and the following C program, "nul": main() { exit(0); } and got the following timings (take with the usual pinch of salt, especially "elapsed" since the system was not single-user): user system elapsed shtest : 10.4 2.1 0:18 shtest echo 57.2 306.0 7:17 shtest /bin/echo 52.2 240.9 8:16 shtest nul 57.9 356.4 11:04 shtest nul.sh 100.8 441.9 15:43 Notes: - "." is the LAST directory on my path, so "nul" requires the longest path search. - "echo" is NOT built in to our version of the shell, which is the Bourne shell as distributed with 4.2, without modification. - All commands were run by "time sh shtest COMMAND >/dev/null". - Timings were done on a VAX 11/750 running 4.2bsd; the kernel recognises "#!" at the start of a script as a "magic number" for exec(), which saves a few cycles in starting up a shell script. The conclusions seem clear: - The time spent in shell interpretation is negligible compared to the time taken to exec other programs. - Searching directories to find commands is cheap compared to fork/exec, but expensive compared to interpreting shell control constructs. - For very small scripts, the startup time of the shell compared to a C program is a significant overhead. Hence, if you have a very small script invoked from the inner loop of another script, it might be worth trying to do something; however, it may well be better to embed the inner script directly in its caller than to translate it to C. Of course, there are many other constructs than "for" and simple variable substitution, but I doubt that any of them is an order of magnitude slower than those. I would also expect exactly the same conclusions to hold for ANY other shell used for script-writing. -- Chris Miller, Heriot-Watt University, Edinburgh ...!ukc!hwcs!chris chris@hwcs.uucp chris@cs.hw.ac.uk