shell compiler?
chris at hwcs.UUCP
chris at hwcs.UUCP
Mon Apr 14 20:37:08 AEST 1986
In article <96 at cstvax.UUCP> scott at 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 at hwcs.uucp chris at cs.hw.ac.uk
More information about the Comp.unix.wizards
mailing list