home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!wupost!sdd.hp.com!uakari.primate.wisc.edu!ames!sun-barr!apple!cambridge.apple.com!bill@cambridge.apple.com
- From: bill@cambridge.apple.com (Bill St. Clair)
- Newsgroups: comp.lang.lisp.mcl
- Subject: Re: PROGV mystery explained
- Message-ID: <9207221906.AA22087@cambridge.apple.com>
- Date: 22 Jul 92 20:50:06 GMT
- Sender: info-mcl-request@cambridge.apple.com
- Lines: 86
- Approved: comp.lang.lisp.mcl@Cambridge.Apple.C0M
- Full-Name: Bill St. Clair
- Original-To: David Kieras <kieras@engin.umich.edu>
- Original-Cc: kab@cambridge.apple.com, info-mcl@cambridge.apple.com
-
- >Kim, your mention that EVAL does COMPILE by default prompts me to
- >ask about the performance implications. How much, relatively &
- >intuitively, am I paying for this? Would I be better off to
- >arrange it so that compile is not the default on EVAL? If so,
- >what is the switch for it? Is this the same control as for the
- >toplevel READ-EVAL loop?
-
- *COMPILE-DEFINITIONS*, which defaults to T, is the switch.
-
- EVAL does not compile everything. It knows that many forms are "easy"
- to evaluate, and handles them. These include symbols, other atoms (which
- are self-evaluating), and lists with a car of QUOTE, PROGN, SETQ,
- EVAL-WHEN, IF, LOCALLY, SYMBOL-MACROLET, MACROLET, UNWIND-PROTECT,
- or any symbol which is not a special form (e.g. macros and regular
- functions). The compiler or the "real" evaluator is called whenever the user
- form specifies any kind of binding or explicitly requests the creation of
- a function object (This list is for 2.0 final. 2.0b1's EVAL invoked the compiler
- a little more often).
-
- As to whether you're better off timewise running with *COMPILE-DEFINITIONS*
- set to NIL, that depends on what you're evaluating.
-
- Here's an example where it doesn't matter, since the evaluated form is
- "simple" enough to grok without considering *COMPILE-DEFINITIONS*:
-
- ? (let ((*compile-definitions* t))
- (without-interrupts
- (time (dotimes (i 1000)
- (eval '(+ 2 3))))))
- (DOTIMES (I 1000) (EVAL '(+ 2 3))) took 238 milliseconds (0.238 seconds) to run.
- 16000 bytes of memory allocated.
- NIL
- ? (let ((*compile-definitions* nil))
- (without-interrupts
- (time (dotimes (i 1000)
- (eval '(+ 2 3))))))
- (DOTIMES (I 1000) (EVAL '(+ 2 3))) took 238 milliseconds (0.238 seconds) to run.
- 16000 bytes of memory allocated.
- NIL
- ?
-
- Here's an example where it is slightly faster to run with
- *COMPILE-DEFINITIONS* bound to NIL:
-
- ? (let ((*compile-definitions* t))
- (without-interrupts
- (time
- (eval '(let ((x 1)) x)))))
- (EVAL '(LET ((X 1)) X)) took 13 milliseconds (0.013 seconds) to run.
- Of that, 1 milliseconds (0.001 seconds) were spent in The Cooperative Multitasking Experience.
- 600 bytes of memory allocated.
- 1
- ? (let ((*compile-definitions* nil))
- (without-interrupts
- (time
- (eval '(let ((x 1)) x)))))
- (EVAL '(LET ((X 1)) X)) took 6 milliseconds (0.006 seconds) to run.
- 800 bytes of memory allocated.
- 1
- ?
-
- If you do more computation, the evaluator starts to show its sluggishness:
-
- ? (let ((*compile-definitions* t))
- (without-interrupts
- (time
- (eval '(let ((x 1))
- (dotimes (i 1000) (incf x))
- x)))))
- (EVAL '(LET ((X 1)) (DOTIMES (I 1000) (INCF X)) X)) took 91 milliseconds (0.091 seconds) to run.
- Of that, 1 milliseconds (0.001 seconds) were spent in The Cooperative Multitasking Experience.
- 1984 bytes of memory allocated.
- 1001
- ? (let ((*compile-definitions* nil))
- (without-interrupts
- (time
- (eval '(let ((x 1))
- (dotimes (i 1000) (incf x))
- x)))))
- (EVAL '(LET ((X 1)) (DOTIMES (I 1000) (INCF X)) X)) took 552 milliseconds (0.552 seconds) to run.
- 2296 bytes of memory allocated.
- 1001
- ?
-
- Note that the evaluator also conses a bit more in these two examples (I
- don't know if this is a general rule).
-