[plt-scheme] getting better speed with JIT
On Dec 2, Jens Axel Soegaard wrote:
> Prabhakar Ragde skrev:
> > Will Clinger recently posted in comp.lang.scheme on the speed of
> > various Scheme implementations, and mentioned in passing that one
> > has to (require mzscheme) to get the JIT to work.
To clarify -- the JIT is always working; it's just that it can do a
better job as Jens described below. Also, even on platforms where the
JIT is unavailable (sparc-solaris), the require line will speed things
up.
> [...]
> However, since it is illegal to mutate a module-required
> variable, the compiler can safely inline the + in:
>
> (require mzscheme)
> (define (foo a b) (+ a b))
>
> There are no problems with module based programs.
And this is related to what Matthew said -- in the above, `+' cannot
change so the compiler can optimize it, but `foo' is not immutable.
This can make a significant difference too. For example (on my
machine),
(define (loop n) (when (> n 0) (loop (- n 1))))
(time (loop 1000000000))
;; -> cpu time: 41489 real time: 41496 gc time: 0
And when you (require mzscheme):
(require mzscheme)
(define (loop n) (when (> n 0) (loop (- n 1))))
(time (loop 1000000000))
;; -> cpu time: 7743 real time: 7745 gc time: 0
Dropping the whole thing into a module makes it even better:
(module foo mzscheme
(define (loop n) (when (> n 0) (loop (- n 1))))
(time (loop 1000000000)))
(require foo)
;; -> cpu time: 3446 real time: 3447 gc time: 0
because it's similar to doing this:
(require mzscheme)
(let ()
(define (loop n) (when (> n 0) (loop (- n 1))))
(time (loop 1000000000)))
;; -> cpu time: 2958 real time: 2960 gc time: 0
IIUC, that trick is in common use in Larceny. I don't really know why
it's faster than the module code -- probably because `foo' can be
folded to a simple loop instead of having a function entry point.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!