|
| I'm getting a vague mental picture, but I don't completely understand
| (yet). Let's say I have a vector of double-floats (call it orig), and
| I want a new vector (squared) whose i'th element is the square of the
| i'th element of the original double-float. (We can also assume that I
| am willing to have my program crash or even produce ill-defined
| results if squaring an element of orig results in an overflow.)
|
| In order to get good performance, will I have to make a single
| function that takes the whole vector and does all the operations
| internally (i.e., a function called square-vector for instance), or
| can I build a higher-order function which takes a procedure like
| square and operates on the elements of the vector? It seems that if
| I'm guaranteed to lose as soon as I call a function with a
| double-float argument, that it's going to be hard to do this fast.
| What're good strategies here?
You can have your square function defined seperately and called by a
function
operating on a vector. Declaim the square function to be inlined, then the
compiler can optimize calls to the function so as to avoid consing up a
boxed
result. For example:
(declaim (inline square))
(defun square (x)(* x x))
(defun square-vector (x z)
(declare (type (simple-array double-float (*)) x z)))
(dotimes (i (min (length x)(length z))
(declare (optimize (safety 0)(fixnum i)))
(setf (aref z i)(square (aref x i))))
z)
Make sure you return something other than a scalar as the result
so the compiler won't have to box up the intermediate results.
Notice that you don't need to put the declarations in 'square' as the
compiler will do the right thing in the calling environment.
So, yes the function 'square' will be inefficient when called from the
top level but can also be very efficient when called in some specific
optimized environment.
Paul