Skip to content

Commit

Permalink
1.0.16.13: use TRANSFORM-LIST-ITEM-SEEK for ADJOIN as well
Browse files Browse the repository at this point in the history
 * Now that the freeze was cancelled, do this properly...
  • Loading branch information
nikodemus committed Apr 29, 2008
1 parent 9cafc84 commit 08fe305
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 37 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
;;;; -*- coding: utf-8; -*-
changes in sbcl-1.0.17 relative to 1.0.16:
* optimization: ADJOIN and PUSHNEW are upto ~70% faster in normal
SPEED policies.
* optimization: APPEND is upto ~10% faster in normal SPEED policies.
* optimization: two argument forms of LAST are upto ~10% faster
in normal SPEED policies.
Expand Down
11 changes: 10 additions & 1 deletion package-data-list.lisp-expr
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,16 @@ is a good idea, but see SB-SYS re. blurring of boundaries."
"SB!EXT" "SB!FASL" "SB!INT" "SB!SYS" "SB!GRAY")
:reexport ("DEF!STRUCT" "DEF!MACRO")
:export ("%ACOS"
"%ACOSH" "%ARRAY-AVAILABLE-ELEMENTS" "%ARRAY-DATA-VECTOR"
"%ACOSH"
"%ADJOIN"
"%ADJOIN-EQ"
"%ADJOIN-KEY"
"%ADJOIN-KEY-EQ"
"%ADJOIN-KEY-TEST"
"%ADJOIN-KEY-TEST-NOT"
"%ADJOIN-TEST"
"%ADJOIN-TEST-NOT"
"%ARRAY-AVAILABLE-ELEMENTS" "%ARRAY-DATA-VECTOR"
"%ARRAY-DIMENSION" "%ARRAY-DISPLACED-P"
"%ARRAY-DISPLACEMENT" "%ARRAY-FILL-POINTER"
"%ARRAY-FILL-POINTER-P" "%ARRAY-RANK"
Expand Down
84 changes: 49 additions & 35 deletions src/code/list.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
;;;; -- WHN 20000127

(declaim (maybe-inline
adjoin tree-equal nth %setnth nthcdr make-list
tree-equal nth %setnth nthcdr make-list
member-if member-if-not tailp union
nunion intersection nintersection set-difference nset-difference
set-exclusive-or nset-exclusive-or subsetp acons
Expand Down Expand Up @@ -1290,44 +1290,58 @@

;;;; Specialized versions

;;; %MEMBER-* and %ASSOC-* functions. The transforms for MEMBER and
;;; ASSOC pick the appropriate version. These win because they have
;;; only positional arguments, the TEST, TEST-NOT & KEY functions are
;;; known to exist (or not), and are known to be functions instead of
;;; function designators. We are also able to transform many common
;;; cases to -EQ versions, which are substantially faster then EQL
;;; using ones.
;;; %ADJOIN-*, %ASSOC-*, and %MEMBER-* functions. Deftransforms
;;; delegate to TRANSFORM-LIST-ITEM-SEEK which picks the appropriate
;;; version. These win because they have only positional arguments,
;;; the TEST, TEST-NOT & KEY functions are known to exist (or not),
;;; and are known to be functions instead of function designators. We
;;; are also able to transform many common cases to -EQ versions,
;;; which are substantially faster then EQL using ones.
(macrolet
((def (funs form &optional variant)
(flet ((%def (name)
`(defun ,(intern (format nil "%~A~{-~A~}~@[-~A~]" name funs variant))
(item list ,@funs)
(declare (optimize speed))
,@(when funs `((declare (function ,@funs))))
(do ((list list (cdr list)))
((null list) nil)
(declare (list list))
(let ((this (car list)))
,(ecase name
(assoc
(if funs
`(when this
(let ((target (car this)))
(let* ((body-loop
`(do ((list list (cdr list)))
((null list) nil)
(declare (list list))
(let ((this (car list)))
,(ecase name
(assoc
(if funs
`(when this
(let ((target (car this)))
(when ,form
(return this))))
;; If there is no TEST/TEST-NOT or
;; KEY, do the EQ/EQL test first,
;; before checking for NIL.
`(let ((target (car this)))
(when (and ,form this)
(return this)))))
(member
`(let ((target this))
(when ,form
(return this))))
;; If there is no TEST/TEST-NOT or
;; KEY, do the EQ/EQL test first,
;; before checking for NIL.
`(let ((target (car this)))
(when (and ,form this)
(return this)))))
(member
`(let ((target this))
(when ,form
(return list))))))))))
(return list))))
(adjoin
`(let ((target this))
(when ,form
(return t))))))))
(body (if (eq 'adjoin name)
`(if (let ,(when (member 'key funs)
`((item (funcall key item))))
,body-loop)
list
(cons item list))
body-loop)))
`(defun ,(intern (format nil "%~A~{-~A~}~@[-~A~]" name funs variant))
(item list ,@funs)
(declare (optimize speed (sb!c::verify-arg-count 0)))
,@(when funs `((declare (function ,@funs))))
,body))))
`(progn
,(%def 'member)
,(%def 'assoc)))))
,(%def 'adjoin)
,(%def 'assoc)
,(%def 'member)))))
(def ()
(eql item target))
(def ()
Expand All @@ -1345,4 +1359,4 @@
(def (test)
(funcall test item target))
(def (test-not)
(not (funcall test-not item target))))
(not (funcall test-not item target))))
3 changes: 3 additions & 0 deletions src/compiler/seqtran.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,9 @@
(deftransform assoc ((item list &key key test test-not) * * :node node)
(transform-list-item-seek 'assoc item list key test test-not node))

(deftransform adjoin ((item list &key key test test-not) * * :node node)
(transform-list-item-seek 'adjoin item list key test test-not node))

(deftransform memq ((item list) (t (constant-arg list)))
(labels ((rec (tail)
(if tail
Expand Down
2 changes: 1 addition & 1 deletion version.lisp-expr
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
"1.0.16.12"
"1.0.16.13"

0 comments on commit 08fe305

Please sign in to comment.