<html><head></head><body><div class="ydp17e0d240yahoo-style-wrap" style="font-family:Helvetica Neue, Helvetica, Arial, sans-serif;font-size:13px;"><div></div>
<div dir="ltr" data-setdir="false">I'm doing this for performance. Here's the whole function; the coefficients typically have between 5-15 elements.<br></div><div dir="ltr" data-setdir="false"><br></div><div dir="ltr" data-setdir="false"><div>(declaim (inline evaluate-polynomial))<br>(defun %evaluate-polynomial (coefficients x)<br> "Return the sum of polynomials, weighted by the list of COEFFICIENTS, at X.<br>X and contents of COEFFICIENTS must be of the same type.<br>COEFFICIENTS are in descending order from the highest degree down to the constant term."<br> (declare (optimize(speed 3)(safety 0))<br> #+sbcl (sb-ext:muffle-conditions sb-ext:compiler-note)) ; Function declared inline, but SBCL whines<br> ;; See https://groups.google.com/forum/#!msg/comp.lang.lisp/AsKvR0emFtU/ILVjmLTlJ50J<br> (assert (and (plusp (length coefficients))<br> (every (lambda (elt)<br> (typep elt (class-of x)))<br> coefficients))<br> (coefficients x)<br> "Coefficients and X must be of the same type.")<br> (etypecase x<br> (double-float<br> (let((sum (car coefficients)))<br> (declare (double-float sum x))<br> (loop for i double-float in (cdr coefficients)<br> do (setf sum (+ i (* x sum))))<br> sum))<br> (single-float<br> (let((sum (car coefficients)))<br> (declare (single-float sum x))<br> (loop for i single-float in (cdr coefficients)<br> do (setf sum (+ i (* x sum))))<br> sum))<br> (fixnum<br> (let((sum (car coefficients)))<br> (declare (fixnum sum x))<br> (loop for i fixnum in (cdr coefficients)<br> do (setf sum (+ i (* x sum))))<br> sum))))<br></div><div><br></div></div><div dir="ltr" data-setdir="false">I haven't needed to optimize to any great degree before, but here we're at the bottom levels and this gets called a great many times. I'm just a little surprised there is such a high cost in typep. As I understand your reply, even doing this over a small sequence is going to kill performance (or rather make the declarations pointless given the cost/benefit of the assert). Your suggestion of a specialized arrays would be a good way out, as I already have one that is frequently used:</div><div dir="ltr" data-setdir="false"><br></div><div dir="ltr" data-setdir="false"><div>(deftype simple-double-float-vector (&optional (length '*))<br> "Simple vector of double-float elements."<br> `(simple-array double-float (,length)))</div><div><br></div></div><div dir="ltr" data-setdir="false">Thanks.<br></div><div dir="ltr" data-setdir="false"><br></div><div dir="ltr" data-setdir="false"><br></div><div dir="ltr" data-setdir="false"><br></div><div><br></div>
</div><div id="ydp6d065141yahoo_quoted_2834134810" class="ydp6d065141yahoo_quoted">
<div style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:13px;color:#26282a;">
<div>
On Thursday, October 24, 2019, 7:38:23 PM GMT+8, Stas Boukarev <stassats@gmail.com> wrote:
</div>
<div><br></div>
<div><br></div>
<div><div dir="ltr">On Thu, Oct 24, 2019 at 10:44 AM Steven Nunez <<a shape="rect" href="mailto:steve_nunez@yahoo.com" rel="nofollow" target="_blank">steve_nunez@yahoo.com</a>> wrote:<br clear="none">><br clear="none">> Okay, having a specialised representation for positive integers makes sense as a further specialisation of INTEGER. I wish this was documented somewhere, a 1 minute google search did not turn up anything.<br clear="none">><br clear="none">> I still have the problem of ensuring that the parameters to a function, a sequence and a number, are all of the same type so I can dispatch on specialised (typed declared) versions of loop. At the moment I have:<br clear="none">><br clear="none">> (assert (and (plusp (length coefficients))<br clear="none">> (every (lambda (elt)<br clear="none">> (typep elt (type-of x)))<br clear="none">> coefficients)))<br clear="none">><br clear="none">> which works fine for single-float and double-float, but fails if any of the coefficients are negative because their type-of is FIXNUM whilst the X or other coefficients may be (INTEGER 0 4611686018427387903)<br clear="none">><br clear="none">> Any ideas?<br clear="none">Are you doing it for performance? Any performance gains you get from<br clear="none">declaring your variables in a loop will be destroyed by performing<br clear="none">typep at runtime.<br clear="none">The cost of determining type-of, parsing it and applying typep on it<br clear="none">is going to be very high, especially if it's done on every element of<br clear="none">a sequence.<br clear="none">If you do need to perform that operation, you can do<br clear="none">(defun foo (x sequence)<br clear="none"> (macrolet ((make-test (x types)<br clear="none"> `(etypecase ,x<br clear="none"> ,@(loop for type in types<br clear="none"> collect `(,type (lambda (x) (typep x ',type)))))))<br clear="none"> (every (make-test x (double-float single-float fixnum))<div class="ydp6d065141yqt6804229022" id="ydp6d065141yqtfd87731"><br clear="none"> sequence)))</div><br clear="none"><br clear="none">Maybe even putting EVERY inside the expansion, to get better inlining.<br clear="none">And handle specialized arrays without going through each element.<div class="ydp6d065141yqt6804229022" id="ydp6d065141yqtfd32659"><br clear="none"></div></div></div>
</div>
</div></body></html>