Re: Request for Clarification on Rationale Shiro Kawai 07 Apr 2006 00:01 UTC

I feel this comparison is somewhat skewed.  The typical
situation where I use multiple values is:

- multiple values are generated for every iteration,
  so mm vs vv test is more close, and
- the expression body of generating multiple values are
  known, so I'd rather use srfi-8's RECEIVE.

And this is the result on Gauche 0.8.6 / P4 2GHz (I use 100times
more iterations as William Clinger did.)

gosh> (time (for-each (lambda (x) ((mm x) list)) (make-list 10000000 1)))
; real  19.542
; user  19.480
; sys    0.060

gosh> (time (for-each (lambda (x) (call-with-values (lambda () (vv x)) list)) (make-list 10000000 1)))
; real  26.579
; user  26.460
; sys    0.110

gosh> (time (for-each (lambda (x) (receive z (vv x) (list z))) (make-list 10000000 1)))
; real  11.805
; user  11.750
; sys    0.040

The point is that the 'call-with-values' version creates
a closure for every iteration, as well as mu version, while
'receive' version can optimize it away.  The same optimization
is done with srfi-11 let-values as well.
(If the optimizer is sufficienty smart, 'call-with-values'
version can also be compiled without creating closures,
given that the binding of 'call-with-values' itself is
not altered elsewhere.)

The difference of mu vs call-with-values did catch my
attention.  There should be some room for improvement.