Subject: Re: macro question
From: Erik Naggum <erik@naggum.net>
Date: Fri, 08 Mar 2002 18:32:48 GMT
Newsgroups: comp.lang.lisp
Message-ID: <3224601177776549@naggum.net>

* Rolf Wester <wester@ilt.fhg.de>
| My point is performance.

  Are you quite sure about that?

| My function is:
| 
| (defun maxwell-v (v temp m)
|   (let ((c1 (* 4.0d0 dpi (expt (/ m (* 2.0d0 dpi +kB+ temp)) 1.5d0)))
|          (c2 (/ (* -1.0d0 m) (* 2.0d0 +kB+ temp))))
|      (* c1 v v(exp (* v v c2)))))
| 
| I don't want to calculate c1 and c2 every time I call the function with
| only v different than in the other calls.

  Common Lisp programmers generally do this with memoization.  Several
  general wrappers exist, but if you make a lot of calls in a row with only
  v varying, as you say, here's a simple solution that computes c1 and c2
  only when temp and m is different from those in the previous call.  It
  would also be natural to declare some types if you want more performance:

(defun maxwell-v (v temp m)
  (declare (optimize (speed 3))
	   (double-float v temp m))
  (let ((memo (load-time-value (vector nil nil nil nil))))
    (declare (simple-vector memo))
    (unless (and (eq (svref memo 0) temp)
		 (eq (svref memo 1) m))
      (setf (svref memo 0) temp)
      (setf (svref memo 1) m)
      (setf (svref memo 2) (* 4.0d0 dpi (expt (/ m (* 2.0d0 dpi +kB+ temp)) 1.5d0)))
      (setf (svref memo 3) (/ (* -1.0d0 m) (* 2.0d0 +kB+ temp))))
    (* v v (the double-float (svref memo 2))
       (exp (* v v (the double-float (svref memo 3)))))))

  This _should_ be faster than calling a closure.

///
-- 
  In a fight against something, the fight has value, victory has none.
  In a fight for something, the fight is a loss, victory merely relief.