From: Steve L. <sjl...@mi...> - 2014-04-24 15:58:12
|
Thank you Christophe! Your explanation if clear and useful, and your example works great. I've been digging a little deeper and using structures as you recommend, which has led me to a similar question. I find that when using structures, SBCL similarly does not infer type when I use (slot-value ...), but if I use the corresponding accessor for the slot, everything works great. This isn't a problem for me (as I'll just use the accessors), but I was curious why this might be. Here is another toy example, which uses a structure A and four methods x, y, z, and w (that all do the same thing differently): (defstruct A (m-num 0 :type fixnum)) ;; Optimizes great! (defmethod x ((a A)) (declare (optimize speed (safety 0))) (incf (a-m-num a))) ;; Also works great! (defmethod y ((a A)) (declare (optimize speed (safety 0))) (with-accessors ((m-num a-m-num)) a (incf m-num))) ;; Can't optimize the incf (defmethod z ((a A)) (declare (optimize speed (safety 0))) (incf (slot-value a 'm-num))) ;; Also can't optimize (because macroexpands to slot-value) (defmethod w ((a A)) (declare (optimize speed (safety 0))) (with-slots (m-num) a (incf m-num))) This example shows that using the accessor (a-m-num ...), or the similar (with-accessors ...) macro, optimizes great. However, using (slot-value ...) or the corresponding (with-slots ...) macro doesn't optimize the incf. Again, not a problem, but I'm curious. Thanks again for all your useful help! Best regards, Steve On Thu, Apr 24, 2014 at 1:41 AM, Christophe Rhodes <cs...@ca...> wrote: > Steve Levine <sjl...@mi...> writes: > > > I have a question about SBCL optimizations for slot types in classes. > I've > > noticed that when using (with-slots ...) in a certain way, I seem to get > a > > lot of "unable to optimize" notices. Here's a toy example: > > > > (defclass A () > > ((m_num > > :type fixnum > > :initform 2))) > > > > > > (defmethod f ((a A)) > > (with-slots (m_num) a > > (incf m_num))) > > The problem with SBCL acting on the information that the slot is > declared to be of type fixnum here, is that the class can be redefined > at any time, including changing any and all slot constraints, *without* > the method needing to be touched at all. So if we compiled the method > function while baking in the fixnumness of the slot, we would have to > invalidate that function on incompatible class redefinition. > > This isn't impossible, but it's hard. Generally, CLOS has enough layers > of indirection that it's not easy to get maximum speed out of it; if > your design has settled down enough that redefinition is not necessary, > you could consider using structures for the things needing type > inference and speed. Alternatively, > (defmethod f ((a A)) > (let ((m (slot-value a 'm_num))) > (declare (type fixnum m) (optimize speed (safety 0))) > (incf m) > (setf (slot-value a 'm_num) m))) > is inelegant but the fixnum addition should be fast. > > Cheers, > > Christophe > |