structures and arrays : one conses the other doesn't
Hi,
Sorry to trouble the list again, but I was wondering if there was any way to
stop the code in function 'testing' below from consing. Basically, I can see
(following on from advice given earlier) how I can avoid consing by 'wrapping'
my floating point ops as array -> array operations (thanks Tim). The code in
the function 'testing2' does this and does not cons. I guess what
I don't understand is why I cannot use structures (as in function 'testing')
to acheive the same effect.
It would basically be a lot 'nicer' to be able to use structures in this way
(for some of my code), rather than arrays.
(defstruct simple-struct
(field-1 0.0D0 :type double-float))
(defparameter sa1 (make-array 1 :element-type 'double-float :initial-element 1.0D0))
(defparameter ss0 (make-simple-struct))
(defparameter sf1 1.0D0)
(defparameter sf2 2.0D0)
(defun testing2 (a b c)
(declare (type double-float b c)
(type (simple-array double-float (*)) a)
(optimize (speed 3) (safety 0) #+LispWorks(float 0) (debug 0)))
(setf (aref a 0) (+ b c))
a)
(defun testing (a b c)
(declare (type double-float b c d)
(type simple-struct a)
(optimize (speed 3) (safety 0) #+LispWorks(float 0) (debug 0)))
(setf (simple-struct-field-1 a) (+ b c))
a)
CL-USER 160 > (time (testing ss0 sf1 sf2))
Timing the evaluation of (TESTING SS0 SF1 SF2)
user time = 0.000
system time = 0.000
Elapsed time = 0:00:00
Allocation = 16 bytes standard / 0 bytes fixlen
0 Page faults
#S(SIMPLE-STRUCT FIELD-1 3.0)
CL-USER 159 > (time (testing2 sa1 sf1 sf2))
Timing the evaluation of (TESTING2 SA1 SF1 SF2)
user time = 0.000
system time = 0.000
Elapsed time = 0:00:00
Allocation = 0 bytes standard / 0 bytes fixlen
0 Page faults
#(3.0)
Thanks again,
Barry.
(BTW : Thanks again to Dave for his performance hint (declaring the type of
the inner sum). But there was a minor bug in the code he posted :
(defun matrix-product (m1 m2 m3)
(declare (type (simple-array single-float (* *)) m1 m2 m3))
(declare (optimize (float 0) (safety 0)))
(loop for i from 0 below (array-dimension m1 0)
do
(loop for j from 0 below (array-dimension m2 1)
with sum of-type single-float = 0F0
do
(loop for alpha from 0 below (array-dimension m1 1)
do (incf sum (* (aref m1 i alpha) (aref m2 alpha j))))
(setf (aref m3 i j) sum)))
m3)
It should be :
(defun matrix-product (m1 m2 m3)
(declare (type (simple-array single-float (* *)) m1 m2 m3)
(optimize (speed 3) (safety 0) (float 0)))
(loop for i fixnum from 0 below (array-dimension m1 0)
do
(loop for j fixnum from 0 below (array-dimension m2 1)
do
(loop for alpha fixnum from 0 below (array-dimension m1 1)
with sum of-type single-float = 0.0F0
do (incf sum (* (aref m1 i alpha) (aref m2 alpha j)))
finally (setf (aref m3 i j) sum))))
m3)
where the inner sum is moved into the inner loop, and the array element set in a
finally clause. Otherwise, the sum is not zeroed until i is incremented.)
--
If in the last few years you haven't discarded a major opinion or
acquired a new one, check your pulse. You may be dead.
-- Gelett Burgess (1866-1951)