Greetings! I was just looking at how gcl compiles a matrix
multiplication today. In short, once one makes sure all the
declarations are kicking in, it appears as if it can get as fast as
native C.
There does appear to be a curent inefficiency in our dotimes
definition, as compared with do and do*. The existing definition is:
(defmacro dotimes ((var form &optional (val nil)) &rest body
&aux (temp (gensym)))
`(do* ((,temp ,form) (,var 0 (1+ ,var)))
((>= ,var ,temp) ,val)
,@body))
If one declares the type of var, optimizations still do not kick in
because the gensym'd temp has no declared type.
I'm proposing the following:
(defmacro dotimes ((var form &optional (val nil)) &rest body
&aux (temp (gensym)) temp1
temp2 temp3 temp4)
`(do* ((,temp ,form) (,var 0 (1+ ,var)))
((>= ,var ,temp) ,val)
,(dolist (temp1 body temp4)
(when (eq (car temp1) 'declare)
(let ((temp2 (cadr temp1)))
(dolist (temp3 (cdr temp2))
(when (eq temp3 var)
(setq temp4 `(declare (,(car temp2) ,temp))))))))
,@body))
This basically will extend the user's possible declaration of var to
that of the integer evaluation of form stored in temp, as would appear
to make sense, as var has to count up to this value in any case.
With this enhancement in my preliminary testing, all loops of the form
'(dotimes (i form) (declare (fixnum i)) ...) have the counting variable
incrementation and comparison fully optimized, i.e. avoiding the
generic number_compare, etc.
So what do the lisp experts think? Am I getting into trouble?