This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

defining a variable inside a Defun

3 posts · 3327 views

I'm trying to show the result I'm after by showing the what I don't want. Here is the code I'm referring to, the way the functions work don't matter...I highlight how long it takes to run, them and that is what matters. Just keep an out because 2 functions in my question have names that are exactly the same except for a % at the front of it's name.


(let ((val nil))
  (defun c-arr-to-vector-float  (a len)
    (cond (val val)
          ((listp a) (progn (setf val (foreign-alloc :float :initial-contents a)) 
			    (%c-arr-to-vector-float val len)))
	  (t nil))))
If I run this:
 (%c-arr-to-vector-float (foreign-alloc :float :initial-contents '(1 2 3)) 3 )
1 million times, it takes 6 seconds. but if define
(foreign-alloc :float :initial-contents (1 2 3)) 
first like:
(defparameter a (foreign-alloc :float :initial-contents '(1 2 3)))
then run
(%c-arr-to-vector-float a len) 
running
(%c-arr-to-vector-float a len) 
only takes .017 seconds...do you see where I'm coming from here...I'm looking to speed up the above function? but each time I run the
c-arr-to-vector-float function
with the let statement above I have to be able to put in a new value, i.e. every time this is run
(c-arr-to-vector-float '(1 2 3) 3) 
(that's name of the defun in the let) the function should operate on the '(123) and if I give it a '(4 5 6) it should operate on that. And I don't want to make someone run the defparameter first each time, I'm trying to make it be automatic and everything inside one s-expression.

Re: defining a variable inside a Defun

It sounds like you are measuring the time to allocate, initialize, and free the "val" parameter a million times.

Is the following what you are looking for?
(defun test ()
  (let ((arr (foreign-alloc :float :initial-contents '(1 2 3))))
    (dotimes (i 1000000)
      (%c-arr-to-vector-float arr 3))))

Re: defining a variable inside a Defun

If I have understood your examples correctly then you want to avoid multiple evaluation of foreign-alloc by caching the old value in a lexical variable.
(let (old-a val)
  (defun c-arr-to-vector-float (a len)
    (cond ((equal a old-a)  ; a is the same list as in the last call
           (%c-arr-to-vector-float val len))
          ((listp a)   ; a is a list but not the same as in the last call
           (setf old-a a
                 val (foreign-alloc :float :initial-contents a))
           (%c-arr-to-vector-float val len)))
          (t nil))))
The list from a is stored in old-a and the return-value of foreign-alloc is stored in val. If the function is called with a list that is not the same list as the list stored in old-a, then the list from a is stored in old-a, the return-value of foreign-alloc is computed and stored in val. If the function is called with a list that is the same list as the list stored in old-a, the old foreign-alloc return-value from val is used instead.

Caching computed values in a hash-table:
;; EQUAL is needed here because the key is a list
(defvar hash-table (make-hash-table :test #'equal))

(defun c-arr-to-vector-float (a len)
  (let ((val (gethash a hash-table)))     ; try to get val from hash-table
    (cond (val (%c-arr-to-vector-float val len)) ; use val from hash-table
          ((listp a)
           (setf val (foreign-alloc :float :initial-contents a)
                 (gethash a hash-table) val)     ; store val in hash-table
           (%c-arr-to-vector-float val len))
          (t nil))))
All return-values of foreign-alloc are stored in the hash-table with the list from a as the respective key. If the function is called with a list who's value is not stored in the hash-table the value is computed once and stored in the hash-table. If the function is called with a list who's value is already stored in the hash-table, the value from the hash-table is used instead.

Special care must be taken that the hash-table doesn't grow bigger than the available memory.

- edgar