Hi,
I am optimizing my code and found that instead of returning multiple
values, SBCL likes to have them packed into a vector with a specialized
element-type (otherwise it complains about doing float to pointer
coercion).
I found that
(make-array 2 :element-type 'double-float :initial-contents (list x y))
is not optimal since the compiler complains. Doing
(let ((a (make-array 2 :element-type 'double-float)))
(setf (aref a 0) x
(aref a 1) y)
a)
makes SBCL happy. Is there a one-liner "neat" way of doing this that I
could not figure out, or should I just pack this up in a macro (for n
arguments)?
Thanks,
Tamas
PS.: I asked about this on the SBCL list but didn't (yet) get a reply.
Tamas K Papp wrote:
> Hi,
>
> I am optimizing my code and found that instead of returning multiple
> values, SBCL likes to have them packed into a vector with a specialized
> element-type (otherwise it complains about doing float to pointer
> coercion).
>
> I found that
>
> (make-array 2 :element-type 'double-float :initial-contents (list x y))
>
> is not optimal since the compiler complains. Doing
>
> (let ((a (make-array 2 :element-type 'double-float)))
> (setf (aref a 0) x
> (aref a 1) y)
> a)
>
> makes SBCL happy. Is there a one-liner "neat" way of doing this that I
> could not figure out, or should I just pack this up in a macro (for n
> arguments)?
>
> Thanks,
>
> Tamas
>
> PS.: I asked about this on the SBCL list but didn't (yet) get a reply.
Wouldn't that be faster (dunno for sure):
(make-array 2 :element-type 'double-float :initial-contents #(1.0d0 2.0d0))
On Mon, 27 Oct 2008 12:15:59 -0700, Dimiter \"malkia\" Stanev wrote:
> Dimiter "malkia" Stanev wrote:
>> Tamas K Papp wrote:
>>> Hi,
>>>
>>> I am optimizing my code and found that instead of returning multiple
>>> values, SBCL likes to have them packed into a vector with a
>>> specialized element-type (otherwise it complains about doing float to
>>> pointer coercion).
>>>
>>> I found that
>>>
>>> (make-array 2 :element-type 'double-float :initial-contents (list x
>>> y))
>>>
>>> is not optimal since the compiler complains. Doing
>>>
>>> (let ((a (make-array 2 :element-type 'double-float)))
>>> (setf (aref a 0) x
>>> (aref a 1) y)
>>> a)
>>>
>>> makes SBCL happy. Is there a one-liner "neat" way of doing this that
>>> I could not figure out, or should I just pack this up in a macro (for
>>> n arguments)?
>>>
>>> Thanks,
>>>
>>> Tamas
>>>
>>> PS.: I asked about this on the SBCL list but didn't (yet) get a reply.
>>
>> Wouldn't that be faster (dunno for sure):
>>
>> (make-array 2 :element-type 'double-float :initial-contents #(1.0d0
>> 2.0d0))
>
> I think it's faster, I've just tested it under SBCL:
Isn't SBCL just folding constants there?
(make-array 2 :element-type 'double-float :initial-contents
(vector x y))
still makes SBCL complain about doing float to pointer coercion.
Tamas
Tamas K Papp wrote:
> On Mon, 27 Oct 2008 12:15:59 -0700, Dimiter \"malkia\" Stanev wrote:
>
>> Dimiter "malkia" Stanev wrote:
>>> Tamas K Papp wrote:
>>>> Hi,
>>>>
>>>> I am optimizing my code and found that instead of returning multiple
>>>> values, SBCL likes to have them packed into a vector with a
>>>> specialized element-type (otherwise it complains about doing float to
>>>> pointer coercion).
>>>>
>>>> I found that
>>>>
>>>> (make-array 2 :element-type 'double-float :initial-contents (list x
>>>> y))
>>>>
>>>> is not optimal since the compiler complains. Doing
>>>>
>>>> (let ((a (make-array 2 :element-type 'double-float)))
>>>> (setf (aref a 0) x
>>>> (aref a 1) y)
>>>> a)
>>>>
>>>> makes SBCL happy. Is there a one-liner "neat" way of doing this that
>>>> I could not figure out, or should I just pack this up in a macro (for
>>>> n arguments)?
>>>>
>>>> Thanks,
>>>>
>>>> Tamas
>>>>
>>>> PS.: I asked about this on the SBCL list but didn't (yet) get a reply.
>>> Wouldn't that be faster (dunno for sure):
>>>
>>> (make-array 2 :element-type 'double-float :initial-contents #(1.0d0
>>> 2.0d0))
>> I think it's faster, I've just tested it under SBCL:
>
> Isn't SBCL just folding constants there?
>
> (make-array 2 :element-type 'double-float :initial-contents
> (vector x y))
>
> still makes SBCL complain about doing float to pointer coercion.
>
> Tamas
Yup, you are right. My mistake. What I did would work only for constants.
I guess then the most optimal way, would be setf-ing them one by one.
I've also tried using vector for initialization, and made the vector to
be on the stack (where the implementation allows by using (declare
(dynamic-extent v)) - but it still produces more code, or conses
(depends on the lisp implementation).
Maybe some macro?
From: D Herring
Subject: Re: making specialized array neatly
Date:
Message-ID: <ge5lst$elm$1@aioe.org>
Tamas K Papp wrote:
> I am optimizing my code and found that instead of returning multiple
> values, SBCL likes to have them packed into a vector with a specialized
> element-type (otherwise it complains about doing float to pointer
> coercion).
>
> I found that
>
> (make-array 2 :element-type 'double-float :initial-contents (list x y))
>
> is not optimal since the compiler complains. Doing
>
> (let ((a (make-array 2 :element-type 'double-float)))
> (setf (aref a 0) x
> (aref a 1) y)
> a)
>
> makes SBCL happy. Is there a one-liner "neat" way of doing this that I
> could not figure out, or should I just pack this up in a macro (for n
> arguments)?
Something like
(defmacro fill-array (type &rest values)
"Initialize an array with values of the given type.
Example: (fill-array 'double-float 1d0 2d0 3d0)"
(let ((l (length values))
(n (gensym)))
`(let ((,n (make-array ,l :element-type ,type)))
,(cons 'setf
(loop for v in values
for i from 0 below l
appending (list (list 'aref n i) v)))
,n)))
? [lightly tested]
- Daniel
D Herring wrote:
> Tamas K Papp wrote:
> > I am optimizing my code and found that instead of returning
> > multiple values, SBCL likes to have them packed into a vector with
> > a specialized element-type (otherwise it complains about doing
> > float to pointer coercion).
> >
> > I found that
> >
> > (make-array 2 :element-type 'double-float :initial-contents (list x
> > y))
> >
> > is not optimal since the compiler complains. Doing
> >
> > (let ((a (make-array 2 :element-type 'double-float)))
> > (setf (aref a 0) x
> > (aref a 1) y)
> > a)
> >
> > makes SBCL happy. Is there a one-liner "neat" way of doing this
> > that I could not figure out, or should I just pack this up in a
> > macro (for n arguments)?
>
> Something like
>
> (defmacro fill-array (type &rest values)
> "Initialize an array with values of the given type.
> Example: (fill-array 'double-float 1d0 2d0 3d0)"
> (let ((l (length values))
> (n (gensym)))
> `(let ((,n (make-array ,l :element-type ,type)))
> ,(cons 'setf
> (loop for v in values
> for i from 0 below l
> appending (list (list 'aref n i) v)))
> ,n)))
>
Ruby:
[1.0, 2.0, 3.0]
From: D Herring
Subject: Re: making specialized array neatly
Date:
Message-ID: <geic9c$1fj$1@aioe.org>
William James wrote:
> D Herring wrote:
>> Tamas K Papp wrote:
>>> I am optimizing my code and found that instead of returning
>>> multiple values, SBCL likes to have them packed into a vector with
>>> a specialized element-type (otherwise it complains about doing
>>> float to pointer coercion).
...
> Ruby:
>
> [1.0, 2.0, 3.0]
CL has array syntax too. But it captures compile-time values and
isn't optimized the way Tamas wanted.
CL-USER> #(1.0 2.0 3.0)
#(1.0 2.0 3.0)
CL-USER> (type-of *)
(SIMPLE-VECTOR 3)
CL-USER> (coerce #(1.0 2.0 3.0) '(simple-array single-float (3)))
#(1.0 2.0 3.0)
CL-USER> (type-of *)
(SIMPLE-ARRAY SINGLE-FLOAT (3))
- Daniel
On 2008-11-01 14:29:00 -0400, "William James" <·········@yahoo.com> said:
> Ruby:
>
> [1.0, 2.0, 3.0]
This is a nice because when you specify the element type as float
ruby's optimizing compiler...
oh, wait...
Raffael Cavallaro wrote:
> On 2008-11-01 14:29:00 -0400, "William James" <·········@yahoo.com> said:
>
>> Ruby:
>>
>> [1.0, 2.0, 3.0]
>
> This is a nice because when you specify the element type as float ruby's
> optimizing compiler...
>
> oh, wait...
>
Well at least it could be implemented :) - but then again, it probably
won't work if you want to change the type of the elements on the fly...
Doesn't V8, or some of the other new and exciting JavaScript
implementations have something like that (run-time auto-specializing
thingie for the arrays?)
It sounds neat :)
On Mon, 27 Oct 2008 17:51:44 +0000, Tamas K Papp wrote:
> is not optimal since the compiler complains. Doing
>
> (let ((a (make-array 2 :element-type 'double-float)))
> (setf (aref a 0) x
> (aref a 1) y)
> a)
>
> makes SBCL happy. Is there a one-liner "neat" way of doing this that I
> could not figure out, or should I just pack this up in a macro (for n
> arguments)?
Nikodemus Siivola gave me a nice compiler macro on sbcl-help which solves
the whole issue. See
http://permalink.gmane.org/gmane.lisp.steel-bank.general/2149
SBCL rocks :-)
Tamas
Tamas K Papp wrote:
> On Mon, 27 Oct 2008 17:51:44 +0000, Tamas K Papp wrote:
>
>> is not optimal since the compiler complains. Doing
>>
>> (let ((a (make-array 2 :element-type 'double-float)))
>> (setf (aref a 0) x
>> (aref a 1) y)
>> a)
>>
>> makes SBCL happy. Is there a one-liner "neat" way of doing this that I
>> could not figure out, or should I just pack this up in a macro (for n
>> arguments)?
>
> Nikodemus Siivola gave me a nice compiler macro on sbcl-help which solves
> the whole issue. See
> http://permalink.gmane.org/gmane.lisp.steel-bank.general/2149
>
> SBCL rocks :-)
>
> Tamas
Love it! Thanks!!!
Tamas K Papp <······@gmail.com> writes:
> Hi,
>
> I am optimizing my code and found that instead of returning multiple
> values, SBCL likes to have them packed into a vector with a specialized
> element-type (otherwise it complains about doing float to pointer
> coercion).
>
> I found that
>
> (make-array 2 :element-type 'double-float :initial-contents (list x y))
>
> is not optimal since the compiler complains. Doing
>
> (let ((a (make-array 2 :element-type 'double-float)))
> (setf (aref a 0) x
> (aref a 1) y)
> a)
>
> makes SBCL happy. Is there a one-liner "neat" way of doing this that I
> could not figure out, or should I just pack this up in a macro (for n
> arguments)?
I think you want a macro. Fortunately it's easy to do:
(defmacro make-typed-vector (type &rest args)
(let ((array-var (gensym "ARRAY-")))
`(let ((,array-var (make-array ,(length args) :element-type ',type)))
,@(loop for arg in args
as index upfrom 0
collect `(setf (aref ,array-var ,index) ,arg))
,array-var)))
And then you just need:
(make-typed-vector double-float x y)
--
Thomas A. Russ, USC/Information Sciences Institute