Comment 4 for bug 1001043

Revision history for this message
James M. Lawrence (llmjjmll) wrote :

Hi, thanks. I experimented with saetp dispatching but haven't found a
satisfactory strategy. I have a vested interest in making MAP-INTO
fast, so it's still something I want to pursue.

The problem I saw with dispatch tables a la vector-subseq* is that the
MAP NIL lambda in MAP-INTO has to keep state, i.e. the index variable.
It's also used to adjust the fill pointer later. We could put a
special variable inside the defuns in the dispatch table for MAP-INTO,
but would incrementing a special variable in a critical inner loop
spoil our efforts?

We could punt on O(1) dispatch, going instead with the worst case of
22 fixnum comparisons,

;;; Expands to a CASE form in which the DISPATCHER macro is called for
;;; each possible array element type of ARRAY.
(defmacro %dispatch-on-element-type (array dispatcher)
  `(case (%other-pointer-widetag ,array)
     ,@(map 'list
            (lambda (saetp)
              `(,(sb!vm:saetp-typecode saetp)
                 (,dispatcher ,(sb!vm:saetp-specifier saetp))))
            sb!vm:*specialized-array-element-type-properties*)))

That macro makes it easy to dispatch to closures. But given that SBCL
should scale both ways -- big arrays and tiny arrays -- the fixnum
comparisons may be spoilers.

I've updated the patch to use WITH-ARRAY-DATA, added some more tests,
and sprinkled some WITH-TESTs around map-tests.impure.lisp.

Is the SIMPLE-STRING dispatch of any value? I was following what the
compiler notes seemed to indicate. If (AREF (THE SIMPLE-VECTOR FOO) N)
is eventually transformed to the equivalent of (SVREF FOO N) then the
aref/svref parameter would be needless, but the disassemblies show a
difference.