chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-users] multiple values in chicken


From: Alex Shinn
Subject: [Chicken-users] multiple values in chicken
Date: Fri, 01 Feb 2008 12:13:02 +0900
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1.50 (darwin)

I really, really, loathe multiple values.  I've argued the reasons
countless times before, and I'm not in the mood to do it again.

What I will do is point out is that the most natural (though not only)
alternative, just returning a first-class list, already has just as
concise syntax if you use MATCH on the result, and for Chicken
specifically is much faster.  In general, unless the compiler natively
takes MV into consideration and goes through the effort to place them
on the stack (a complication which can make other optimizations more
difficult, and which few compilers do anyway), then LIST is usually at
least as fast as VALUES.

Specifically, if you have

  (receive (foo bar) (values baz qux) ...)

then you can replace this with

  (match (list baz qux)
    ((foo bar) ...))

or you can abbreviate it with a BIND macro like the one in the
benchmarks below:

  (bind (foo bar) (list baz qux) ...)

How do the runtimes compare?

---- VALUES --------------------------------------------------
  35.949 seconds elapsed
     0.4 seconds in (major) GC
       0 mutations
     760 minor GCs
     960 major GCs
---- LIST ----------------------------------------------------
    2.17 seconds elapsed
  7.e-03 seconds in (major) GC
       0 mutations
    3266 minor GCs
       8 major GCs

That's right, multiple values are more than 10x SLOWER than just using
a list in Chicken.  This is partly because MV has to perform more
checks and partly because Chicken has optimized lists very well (as
any good Lisp compiler should).  You can even shave off a few more
milliseconds in the list case by matching (foo bar . _).

-- 
Alex


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (car+cdr/values pair) (values (car pair) (cdr pair)))

(print "---- VALUES --------------------------------------------------")
(gc)
(time (do ((i 1 (+ i 1)))
          ((= i 10000000))
        (receive (kar kdr) (car+cdr/values '(1 . 2))
          (+ kar kdr))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (car+cdr/list pair) (list (car pair) (cdr pair)))

(define-macro (bind pat expr . body)
  `(match ,expr (,pat ,@body)))

(print "---- LIST ----------------------------------------------------")
(gc)
(time (do ((i 1 (+ i 1)))
          ((= i 10000000))
        (bind (kar kdr) (car+cdr/list '(1 . 2))
          (+ kar kdr))))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]