gjc@paradigm.com (01/30/90)
There used to be a saying, FUNCALL CONSIDERED HARMFULL.. In article <1990Jan28.175437.19293@hellgate.utah.edu>, sandra%defun.utah.edu@cs.utah.edu (Sandra J Loosemore) writes: > In article <3277@accuvax.nwu.edu> krulwich@ils.nwu.edu (Bruce Krulwich) writes: >>Rough experiments in Lucid CL (on a SPARCstation) indicate that there is >>indeed twice the procedure-call overhead in calling a closure stored in a >>lexically bound variable as in calling a global function (stored in a >>symbol's function slot). > > Many implementations do optimize FUNCALL heavily. It is theoretically > possible to compile FUNCALL to be just as efficient as an ordinary > call to a named global function ... Enough theory, here are some fun-facts-to-know and tell. (1) In the MIT CADR or LMI LAMBDA lispmachine (FUNCALL F X) and (F X) compiled into *exactly* the same machine instructions. (2) The case (FUNCALL F X) where F was a local variable was very slightly, but measurably FASTER than the case of (F X) where F was a "global" (3) Symbolics and then later Texas Instruments improved on the instruction set such that (FUNCALL F X) and (F X) were indeed different, resulting in some extra overhead for the FUNCALL case, although it is very difficult to measure the difference. (4) On a VAX it is quite easy to implement lexical closures in such a way (inline-code trampolines) such that the two cases produce the same instructions. (5) On some RISC architectures, e.g. SPARC from SUN, there is different code produce for {This is C code now, not lisp:} (*F)(X); vs. F(X); and in-fact a little subroutine called POINTERCALL is called in the (*F)(X); case. -GJC (Also known as the John Silber of Lisp Implementors?)
pf@islington-terrace.csc.ti.com (Paul Fuqua) (02/17/90)
Date: Monday, January 29, 1990 1:11pm (CST)
From: gjc at paradigm.com
Subject: Re: FUNCALL question, fun facts
Newsgroups: comp.lang.lisp
(1) In the MIT CADR or LMI LAMBDA lispmachine (FUNCALL F X) and (F X) compiled
into *exactly* the same machine instructions.
(2) The case (FUNCALL F X) where F was a local variable was very slightly,
but measurably FASTER than the case of (F X) where F was a "global"
(3) Symbolics and then later Texas Instruments improved on the instruction
set such that (FUNCALL F X) and (F X) were indeed different, resulting
in some extra overhead for the FUNCALL case, although it is very
difficult to measure the difference.
Regarding the TI Explorer, I beg to differ. I wrote the Release 3
function-calling microcode, which is substantially unchanged through the
current release, so I have some idea what I'm talking about.
There is only one batch of CALL instructions, used identically by both
(FUNCALL F X) and (F X). A CALL will be slightly faster if the function
is a local variable, an argument, or popped from the stack, because
stack references don't involve an external memory access. If the
function is global, the additional overhead is two memory references.
The additional overhead of a lexical closure is mostly just extracting
the environment structure and setting it up in a local variable.
Paul Fuqua pf@csc.ti.com
{smu,texsun,cs.utexas.edu,rice}!ti-csl!pf
Texas Instruments Computer Science Center
PO Box 655474 MS 238, Dallas, Texas 75265