Optimize vector of floats access
I have the following code to provide (ideally) efficient access to vectors of floats. On my machine a call of (test-speed 1000000) under LW 5.1.1 for Linux 64 bit takes 0.440 seconds. On the same machine using SBCL 1.0.22 it takes 0.051 seconds, so nearly 10 times faster. 1. Is there something relatively simple I can do to get similar or even just improved performance under LispWorks? Note that I didn't start out with CFFI but ended up there when make-array ... :element-type 'single-float etc. didn't get me what I wanted. I'd be happy to drop the CFFI if possible. 2. I also tried typed-aref but (foo) below returns 0.0 for reasons I do not understand... 3. Off topic but curiously if you change the 28.0 to 28 in test-speed and recompile under SBCL it only takes 0.016 seconds. What's the reason for that? Cheers, Greg -- (in-package :cl-user) (defun fill-float-vector (vector contents) (loop for i from 0 for value in contents do (setf (cffi:mem-aref vector :float i) value)) vector) (defmacro with-float-vector ((vector-name count contents) &body body) `(let ((,vector-name (cffi:foreign-alloc :float :count ,count))) (fill-float-vector ,vector-name ,contents) (unwind-protect (progn ,@body) (cffi:foreign-free ,vector-name)))) (defun lookup-uk-stake-range-value (price prices values length) (declare (optimize speed (safety 0) #+:lispworks (float 0))) (declare (type fixnum length)) (dotimes (i length) (declare (type fixnum i) (type single-float price)) (when (< price (cffi:mem-aref prices :float i)) (return-from lookup-uk-stake-range-value (cffi:mem-aref values :float i))))) (defun test-speed (iterations) (let ((length 15)) (with-float-vector (prices length '(1.01 1.25 1.50 1.75 2.0 3.0 4.0 5.0 7.0 9.0 12.0 15.0 20.0 25.0 35.0)) (with-float-vector (values length '(1.0 1.0149 0.9653 1.0331 1.1320 1.1390 0.9225 0.9014 0.9885 0.8312 0.9048 0.7822 0.9783 1.0267 0.9808)) (time (dotimes (i iterations) (lookup-uk-stake-range-value 28.0 prices values length))))))) #+:lispworks (defun foo () (declare (optimize speed (safety 0) (float 0))) (let ((vec (sys:make-typed-aref-vector 8))) (dotimes (i 8) (setf (sys:typed-aref 'single-float vec i) 1.0)) (sys:typed-aref 'single-float vec 0)))