From: Pillsy
Subject: Why does this cons so much?
Date: 
Message-ID: <1166643574.841750.63720@t46g2000cwa.googlegroups.com>
So, in SBCL, you get this when you do a loop and INCF a double-float by
another double-float:

* (time (let ((r 0d0))
	        (dotimes (i 100000)
		  (incf r 1d0))))

Evaluation took:
  0.0 seconds of real time
  2.43e-4 seconds of user run time
  2.e-6 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  0 bytes consed.
NIL

but you get this if you use a class and an accessor:

* (defclass move ()
	((rate :initarg :rate :accessor rate)))

#<STANDARD-CLASS MOVE>

* (time (let ((m (make-instance 'move :rate 0d0)))
	        (declare (inline rate))
	        (dotimes (i 100000)
		  (incf (the double-float (rate m)) 1d0))))

Evaluation took:
  0.005 seconds of real time
  0.004387 seconds of user run time
  2.8e-5 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  1,601,528 bytes consed.
NIL

Now I'm not surprised that it's a little slower (at ~10^-8 s/call it's
not a big deal for me), but the consing makes me think that it's doing
something like consing up a float each time, instead of modifying the
one it already has. That is a bit of an issue for me. Is there any way
to get around this? 

TIA,
Pillsy

From: ··@codeartist.org
Subject: Re: Why does this cons so much?
Date: 
Message-ID: <1166648623.956496.36080@48g2000cwx.googlegroups.com>
Pillsy schrieb:

> Now I'm not surprised that it's a little slower (at ~10^-8 s/call it's
> not a big deal for me), but the consing makes me think that it's doing
> something like consing up a float each time, instead of modifying the
> one it already has. That is a bit of an issue for me. Is there any way
> to get around this?

If you store the double-float into a slot of an object, it has to get
boxed by sbcl. So you indeed box one new double-float per round. If you
do a lexical binding, for collecting the value, then the consing should
disapear.

ciao,
Jochen
From: Juho Snellman
Subject: Re: Why does this cons so much?
Date: 
Message-ID: <slrneojfk6.mae.jsnell@sbz-30.cs.Helsinki.FI>
Pillsy <·········@gmail.com> wrote:
> Now I'm not surprised that it's a little slower (at ~10^-8 s/call it's
> not a big deal for me), but the consing makes me think that it's doing
> something like consing up a float each time, instead of modifying the
> one it already has.

The float it already has can't be modified, since numbers are
immutable. (And must be immutable, since the same number object might
be stored in several places).

> That is a bit of an issue for me. Is there any way to get around this? 

Use a structure instead of a CLOS class.

(defstruct move
  (rate nil :type double-float))
  
(time (let ((m (make-move :rate 0d0)))
        (dotimes (i 100000)
          (incf (the double-float (move-rate m)) 1d0))))

-- 
Juho Snellman
From: Ivan Boldyrev
Subject: Re: Why does this cons so much?
Date: 
Message-ID: <huap54-age.ln1@ibhome.cgitftp.uiggm.nsc.ru>
On 9695 day of my life Pillsy wrote:
> ... consing makes me think that it's doing something like consing up
> a float each time, instead of modifying the one it already has.

You cannot modify float because it is kind of "primitive", stateless
object.

> That is a bit of an issue for me.  Is there any way to get around
> this?

If you use CMUCL/SBCL or some other optimizing implementation, you may
use structs.  Structs in these implementation can keep unboxed floats
(like C structs):

CL-USER> (defstruct move
           (rate 0d0 :type double-float))
MOVE
CL-USER> (time (let ((m (make-move :rate 0d0)))
	        (declare (inline move-rate))
	        (dotimes (i 100000)
		  (incf (the double-float (move-rate m)) 1d0))))
Evaluation took:
  0.001 seconds of real time
  0.0 seconds of user run time
  0.0 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  0 bytes consed.


-- 
Ivan Boldyrev

Violets are red, Roses are blue. //
I'm schizophrenic, And so am I.