[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

NMAP innefficiency

From: Steve Bacher (C.S.Draper Lab)
NMAP and MAP don't need to use LENGTH or ELT to process lists if the
compiler can determine that all the sequences passed to it are lists.
In this case, the lists can be CDR'd down in traditional LISP 1.5
fashion until one of the sublists is ENDP.  If, on the other hand,
you wish to mix lists and sequences, you probably don't care much about
efficiency anyway.
Possible compiler transforms:
 (map 'list fun list1 list2 list3) --->
 (do ((g1 list1 (cdr g1))
      (g2 list2 (cdr g2))
      (g3 list3 (cdr g3))
      (result '()))
     ((or (endp g1) (endp g2) (endp g3)) (nreverse result))
     (push (funcall fun (car g1) (car g2) (car g3)) result))
 (nmap rlist fun list1 list2 list3) --->
 (do ((gr rlist (cdr gr))
      (g1 list1 (cdr g1))
      (g2 list2 (cdr g2))
      (g3 list3 (cdr g3)))
     ((or (endp gr) (endp g1) (endp g2) (endp g3)) rlist)
     (setf (car gr) (funcall fun (car g1) (car g2) (car g3))))
Of course, there are better ways of doing MAP than using NREVERSE,
but this is just so you can see what I have in mind.
This solution takes into account the case where the list to be updated
is shorter than any of the other argument sequences.